home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 140 / Gekkan Dennou Club - 2000.1 Vol. 140 (Japan).7z / Gekkan Dennou Club - 2000.1 Vol. 140 (Japan) (Track 1).bin / tools / has060 / hassrc87.lzh / fexpr.s < prev    next >
Text File  |  1999-10-06  |  60KB  |  2,871 lines

  1. ;----------------------------------------------------------------
  2. ;    X68k High-speed Assembler
  3. ;        浮動小数点演算
  4. ;        < fexpr.s >
  5. ;
  6. ;    $Id: fexpr.s,v 1.8  1999 10/ 6(Wed) 14:54:26 M.Kamada Exp $
  7. ;
  8. ;        Copyright 1990-94  by Y.Nakamura
  9. ;                  1997-99  by M.Kamada
  10. ;----------------------------------------------------------------
  11.  
  12.     .include    has.equ
  13.     .include    register.equ
  14.     .include    tmpcode.equ
  15.     .include    symbol.equ
  16.  
  17.     .cpu    68000
  18.     .text
  19.  
  20.  
  21. ;----------------------------------------------------------------
  22. ;    浮動小数点式を計算する
  23. ;    in :a0 = コード化した式を指すポインタ / (CMDOPSIZE) = 結果のサイズ
  24. ;    out:d0:d1:d2 = 結果
  25. calcfexpr::
  26.     movem.l    d3-d7/a1,-(sp)
  27.     bsr    calcfex_xoror        ;式の値を得る(拡張精度実数で計算する)
  28.     pea.l    (calcfexpr9,pc)
  29.     move.b    (CMDOPSIZE,a6),d7    ;結果を必要な精度に変換する
  30.     cmpi.b    #SZ_SHORT,d7
  31.     beq    xtos
  32.     cmpi.b    #SZ_DOUBLE,d7
  33.     beq    xtod
  34.     cmpi.b    #SZ_PACKED,d7
  35.     beq    xtop
  36.     addq.l    #4,sp
  37.     swap.w    d0            ;(SZ_EXTEND)
  38.     clr.w    d0
  39. calcfexpr9:
  40.     movem.l    (sp)+,d3-d7/a1
  41.     rts
  42.  
  43. ;----------------------------------------------------------------
  44. calcfex_xoror:                ;xor/or
  45.     bsr    calcfex_and
  46. calcfex_xoror1:
  47.     move.w    (a0),d7
  48.     move.w    #OP_XOR|OT_OPERATOR,d6
  49.     cmp.w    d6,d7
  50.     beq    calcfex_xoror3
  51.     cmp.w    #'^'|OT_CHAR,d7
  52.     beq    calcfex_xoror3
  53.     move.w    #OP_OR|OT_OPERATOR,d6
  54.     cmp.w    d6,d7
  55.     beq    calcfex_xoror3
  56.     cmp.w    #'|'|OT_CHAR,d7
  57.     beq    calcfex_xoror3
  58.     rts
  59.  
  60. calcfex_xoror3:
  61.     lea.l    (calcfex_and,pc),a1
  62.     bsr    calcfex_intop2
  63.     bra    calcfex_xoror1
  64.  
  65. ;----------------------------------------------------------------
  66. calcfex_and:                ;and
  67.     bsr    calcfex_cmp
  68. calcfex_and1:
  69.     move.w    (a0),d7
  70.     move.w    #OP_AND|OT_OPERATOR,d6
  71.     cmp.w    d6,d7
  72.     beq    calcfex_and3
  73.     cmp.w    #'&'|OT_CHAR,d7
  74.     beq    calcfex_and3
  75.     rts
  76.  
  77. calcfex_and3:
  78.     lea.l    (calcfex_cmp,pc),a1
  79.     bsr    calcfex_intop2
  80.     bra    calcfex_and1
  81.  
  82. ;----------------------------------------------------------------
  83. calcfex_cmp:                ;比較
  84.     bsr    calcfex_addsub
  85. calcfex_cmp1:
  86.     move.l    (a0),d6
  87.     swap.w    d6
  88.     move.w    d6,d7
  89.     clr.b    d7            ;and.w #$FF00,d7
  90.     cmp.w    #OT_OPERATOR,d7
  91.     bne    calcfex_cmp11
  92.     cmp.b    #OP_EQ,d6
  93.     blo    calcfex_cmp10
  94.     cmp.b    #OP_SGE,d6
  95.     bls    calcfex_cmp2
  96. calcfex_cmp10:
  97.     rts
  98.  
  99. calcfex_cmp11:
  100.     move.l    d6,d7
  101.     moveq.l    #OP_EQ,d6
  102.     cmp.l    #('='|OT_CHAR)+(('='|OT_CHAR)<<16),d7
  103.     beq    calcfex_cmp22
  104.     cmp.w    #'='|OT_CHAR,d7
  105.     beq    calcfex_cmp2
  106.     moveq.l    #OP_NE,d6
  107.     cmp.l    #('<'|OT_CHAR)+(('>'|OT_CHAR)<<16),d7
  108.     beq    calcfex_cmp22
  109.     cmp.l    #('!'|OT_CHAR)+(('='|OT_CHAR)<<16),d7
  110.     beq    calcfex_cmp22
  111.     moveq.l    #OP_LE,d6
  112.     cmp.l    #('<'|OT_CHAR)+(('='|OT_CHAR)<<16),d7
  113.     beq    calcfex_cmp22
  114.     moveq.l    #OP_GE,d6
  115.     cmp.l    #('>'|OT_CHAR)+(('='|OT_CHAR)<<16),d7
  116.     beq    calcfex_cmp22
  117.     moveq.l    #OP_LT,d6
  118.     cmp.w    #'<'|OT_CHAR,d7
  119.     beq    calcfex_cmp2
  120.     moveq.l    #OP_GT,d6
  121.     cmp.w    #'>'|OT_CHAR,d7
  122.     beq    calcfex_cmp2
  123.     rts
  124.  
  125. calcfex_cmp22:
  126.     addq.l    #2,a0
  127. calcfex_cmp2:
  128.     lea.l    (calcfex_addsub,pc),a1
  129.     bsr    calcfex_op2
  130.     bra    calcfex_cmp1
  131.  
  132. ;----------------------------------------------------------------
  133. calcfex_addsub:                ;加減算
  134.     bsr    calcfex_muldiv
  135. calcfex_addsub1:
  136.     move.w    (a0),d7
  137.     moveq.l    #OP_ADD,d6
  138.     cmp.w    #'+'|OT_CHAR,d7
  139.     beq    calcfex_addsub2
  140.     moveq.l    #OP_SUB,d6
  141.     cmp.w    #'-'|OT_CHAR,d7
  142.     beq    calcfex_addsub2
  143.     rts
  144.  
  145. calcfex_addsub2:
  146.     lea.l    (calcfex_muldiv,pc),a1
  147.     bsr    calcfex_op2
  148.     bra    calcfex_addsub1
  149.  
  150. ;----------------------------------------------------------------
  151. calcfex_muldiv:                ;乗除算
  152.     bsr    calcfex_unary
  153. calcfex_muldiv1:
  154.     move.l    (a0),d6
  155.     swap.w    d6
  156.     move.w    d6,d7
  157.     clr.b    d7            ;and.w #$FF00,d7
  158.     cmp.w    #OT_OPERATOR,d7
  159.     bne    calcfex_muldiv11
  160. .if 0
  161.     cmp.b    #OP_MOD,d6
  162. .else
  163.     cmp.b    #OP_SHR,d6
  164. .endif
  165.     blo    calcfex_muldiv10
  166.     cmp.b    #OP_ASR,d6
  167.     bls    calcfex_muldiv3
  168. calcfex_muldiv10:
  169.     rts
  170.  
  171. calcfex_muldiv11:
  172.     move.l    d6,d7
  173.     moveq.l    #OP_MUL,d6
  174.     cmp.w    #'*'|OT_CHAR,d7
  175.     beq    calcfex_muldiv2
  176.     moveq.l    #OP_DIV,d6
  177.     cmp.w    #'/'|OT_CHAR,d7
  178.     beq    calcfex_muldiv2
  179.     moveq.l    #OP_SHR,d6
  180.     cmp.l    #('>'|OT_CHAR)+(('>'|OT_CHAR)<<16),d7
  181.     beq    calcfex_muldiv32
  182.     moveq.l    #OP_SHL,d6
  183.     cmp.l    #('<'|OT_CHAR)+(('<'|OT_CHAR)<<16),d7
  184.     beq    calcfex_muldiv32
  185.     rts
  186.  
  187. calcfex_muldiv22:
  188.     addq.l    #2,a0
  189. calcfex_muldiv2:
  190.     lea.l    (calcfex_unary,pc),a1
  191.     bsr    calcfex_op2
  192.     bra    calcfex_muldiv1
  193.  
  194. calcfex_muldiv32:
  195.     addq.l    #2,a0
  196. calcfex_muldiv3:
  197.     lea.l    (calcfex_unary,pc),a1
  198.     bsr    calcfex_intop2
  199.     bra    calcfex_muldiv1
  200.  
  201. ;----------------------------------------------------------------
  202. calcfex_unary:                ;単項式
  203.     move.w    (a0),d7
  204.     cmp.w    #'-'|OT_CHAR,d7
  205.     beq    calcfex_neg
  206.     cmp.w    #'+'|OT_CHAR,d7
  207.     beq    calcfex_prime0
  208.     move.b    d7,d6
  209.     clr.b    d7            ;and.w #$FF00,d7
  210.     cmp.w    #OT_OPERATOR,d7
  211.     bne    calcfex_prime
  212.     cmp.b    #OP_NOT,d6
  213.     blo    calcfex_prime
  214.     cmp.b    #OP_NUL,d6
  215.     bls    calcfex_unary_intop1
  216.     cmp.b    #OP_NOTB,d6
  217.     blo    calcfex_prime
  218. calcfex_unary_intop1:
  219.     lea.l    (calcfex_prime,pc),a1
  220.     bra    calcfex_intop1
  221.  
  222. calcfex_neg:
  223.     pea.l    (xneg,pc)
  224. ;    bra    calcfex_prime0
  225. ;----------------------------------------------------------------
  226. calcfex_prime0:
  227.     addq.l    #2,a0
  228. calcfex_prime:                ;一次式
  229.     move.w    (a0)+,d6
  230.     cmp.w    #'('|OT_CHAR,d6
  231.     beq    calcfex_paren
  232.     move.w    d6,d7
  233.     clr.b    d6            ;and.w #$FF00,d6
  234.     sub.w    d6,d7            ;and.w #$00FF,d7
  235.     cmp.w    #OT_REAL,d6
  236.     beq    calcfex_real
  237.     cmp.w    #OT_VALUEB,d6
  238.     beq    calcfex_valueb
  239.     cmp.w    #OT_VALUEW,d6
  240.     beq    calcfex_valuew
  241.     cmp.w    #OT_VALUE,d6
  242.     beq    calcfex_value
  243.     cmp.w    #OT_VALUEQ,d6
  244.     beq    calcfex_valueq
  245.     cmp.w    #OT_SYMBOL,d6
  246.     beq    calcfex_symbol
  247.     cmp.w    #OT_STR,d6
  248.     bne    exprerr            ;文字列でなければエラー
  249.     tst.w    d7
  250.     beq    exprerr            ;ヌルストリング→エラー
  251.     cmp.w    #4,d7
  252.     bhi    exprerr            ;4文字以上→エラー
  253.     subq.w    #1,d7
  254.     moveq.l    #0,d0            ;文字列
  255. calcfex_str:
  256.     asl.l    #8,d0
  257.     move.b    (a0)+,d0
  258.     dbra    d7,calcfex_str
  259.     move.l    a0,d1
  260.     doeven    d1
  261.     movea.l    d1,a0
  262.     bsr    ltox
  263.     bra    calcfex_size
  264.  
  265. calcfex_real:                ;浮動小数点実数値
  266.     move.w    (a0)+,d0
  267.     move.l    (a0)+,d1
  268.     move.l    (a0)+,d2
  269.     bra    calcfex_size
  270.  
  271. calcfex_valueq:
  272.     move.l    (a0)+,d1        ;上位32bit
  273.     move.l    (a0)+,d0        ;下位32bit
  274.     bsr    qtox
  275.     bra    calcfex_size
  276.  
  277. calcfex_value:                ;数値
  278.     move.l    (a0)+,d0
  279.     bsr    ltox
  280.     bra    calcfex_size
  281.  
  282. calcfex_valuew:
  283.     moveq.l    #0,d0
  284.     move.w    (a0)+,d0
  285.     bsr    ltox
  286.     bra    calcfex_size
  287.  
  288. calcfex_valueb:
  289.     moveq.l    #0,d0
  290.     move.b    d7,d0
  291.     bsr    ltox
  292.     bra    calcfex_size
  293.  
  294. calcfex_symbol:                ;シンボル
  295.     movea.l    (a0)+,a1
  296.     cmpi.b    #ST_REAL,(SYM_TYPE,a1)    ;浮動小数点実数シンボル
  297.     beq    calcfex_symreal
  298.     cmpi.b    #ST_LOCAL,(SYM_TYPE,a1)    ;(ST_VALUE or ST_LOCAL)
  299.     bhi    exprerr
  300.     cmpi.b    #SA_DEFINE,(SYM_ATTRIB,a1)
  301.     blo    exprerr            ;値が定まっていない
  302.     tst.b    (SYM_SECTION,a1)    ;(cmpi.b #SECT_ABS,(SYM_SECTION,a1))
  303.     bne    exprerr            ;定数でない
  304.     move.l    (SYM_VALUE,a1),d0
  305.     bsr    ltox
  306.     bra    calcfex_size
  307.  
  308. calcfex_symreal:
  309.     move.b    (SYM_FSIZE,a1),d7    ;シンボルのサイズ
  310.     bmi    calcfex_symreal01    ;シンボルが定義されていない
  311.     move.l    (SYM_FVPTR,a1),a1    ;シンボル値へのポインタ
  312.     movem.l    (a1),d0-d2        ;シンボル値を得る
  313.     subq.b    #SZ_SINGLE,d7
  314.     beq    calcfex_symreal_single
  315.     subq.b    #SZ_DOUBLE-SZ_SINGLE,d7
  316.     beq    calcfex_symreal_double
  317.     subq.b    #SZ_PACKED-SZ_DOUBLE,d7
  318.     beq    calcfex_symreal_packed
  319.     swap.w    d0
  320.     bsr    normalize
  321.     bra    calcfex_size
  322.  
  323. calcfex_symreal01:
  324. ;ここでは(SYM_TYPE,a1)=ST_REALなのでローカルシンボルは考えなくてよい
  325.     move.l    a1,(ERRMESSYM,a6)
  326.     bra    undefsymerr
  327.  
  328. calcfex_symreal_single:
  329.     bsr    stox
  330.     bra    calcfex_size
  331.  
  332. calcfex_symreal_double:
  333.     bsr    dtox
  334.     bra    calcfex_size
  335.  
  336. calcfex_symreal_packed:
  337.     bsr    ptox
  338.     bra    calcfex_size
  339.  
  340. calcfex_paren:
  341.     bsr    calcfex_xoror
  342.     cmpi.w    #')'|OT_CHAR,(a0)+
  343.     bne    exprerr            ;括弧が閉じていない
  344. ;サイズ指定を処理する
  345. calcfex_size:
  346.     cmpi.b    #OT_SIZE>>8,(a0)
  347.     beq    calcfex_size_0        ;サイズ指定あり
  348. calcfex_size_extend:            ;何もしない
  349.     rts
  350.  
  351. calcfex_size_0:
  352.     move.w    (a0)+,d6
  353.     subq.b    #SZ_WORD,d6
  354.     bcs    calcfex_size_byte
  355.     beq    calcfex_size_word
  356.     subq.b    #SZ_SHORT-SZ_WORD,d6
  357.     bcs    calcfex_size_long
  358. ;    beq    calcfex_size_single
  359.     subq.b    #SZ_DOUBLE-SZ_SHORT,d6
  360.     bcs    calcfex_size_single
  361.     beq    calcfex_size_double
  362.     subq.b    #SZ_PACKED-SZ_DOUBLE,d6
  363.     bcs    calcfex_size_extend
  364.     beq    calcfex_size_packed
  365. ;.qの処理
  366. calcfex_size_quad:
  367.     bsr    calcfex_size_int
  368.     cmp.w    #63,d6
  369.     bgt    overflowerr        ;絶対値が2^64以上
  370.     beq    calcfex_size_int_max
  371.     rts
  372.  
  373. ;.lの処理
  374. calcfex_size_long:
  375.     bsr    calcfex_size_int
  376.     cmp.w    #31,d6
  377.     bgt    overflowerr        ;絶対値が2^32以上
  378.     beq    calcfex_size_int_max
  379.     rts
  380.  
  381. ;.wの処理
  382. calcfex_size_word:
  383.     bsr    calcfex_size_int
  384.     cmp.w    #15,d6
  385.     bgt    overflowerr        ;絶対値が2^16以上
  386.     beq    calcfex_size_int_max
  387.     rts
  388.  
  389. ;.bの処理
  390. calcfex_size_byte:
  391.     bsr    calcfex_size_int
  392.     cmp.w    #7,d6
  393.     bgt    overflowerr        ;絶対値が2^8以上
  394.     beq    calcfex_size_int_max
  395.     rts
  396.  
  397. calcfex_size_int_max:
  398.     tst.w    d0
  399.     bpl    overflowerr        ;2^63以上
  400.     tst.l    d2
  401.     bne    overflowerr        ;-2^63未満
  402.     cmp.l    #$80000000,d1
  403.     bne    overflowerr        ;-2^63未満
  404.     rts
  405.  
  406. ;整数に丸める
  407. ;    アンダーフローは0
  408. ;    INFやNANはエラー
  409. ;<d0.w:d1.l:d2.l:拡張精度浮動小数点数
  410. ;>d6.w:指数部(ベースは0,仮数部の符号は含まず)
  411. calcfex_size_int:
  412.     move.w    d0,d6
  413.     and.w    #$7FFF,d6
  414.     sub.w    #$3FFF,d6        ;小数点の位置
  415.     bsr    calcfex_rn        ;整数に丸める
  416.     move.w    d0,d6            ;丸めた後の指数部をテストしなければならない
  417.                     ;(丸めた結果1になったり整数範囲内にぎりぎり
  418.                     ;入り切る数を許すため)
  419.     and.w    #$7FFF,d6
  420.     cmp.w    #$7FFF,d6
  421.     beq    calcfex_size_int_error    ;INFかNAN
  422.     sub.w    #$3FFF,d6
  423.     bpl    calcfex_size_int_done    ;絶対値が1以上(上限はチェックしない)
  424.     addq.l    #4,sp            ;calcfex_size_{quad/long/word/byte}から抜ける
  425.     and.w    #$8000,d0        ;アンダーフロー(非正規化数を含む)
  426.     moveq.l    #0,d1
  427.     moveq.l    #0,d2
  428. calcfex_size_int_done:
  429.     rts
  430.  
  431. calcfex_size_int_error:
  432.     tst.l    d1
  433.     bne    ilvalueerr        ;NANは整数化できない
  434.     tst.l    d2
  435.     bne    ilvalueerr        ;NANは整数化できない
  436.     bra    overflowerr        ;INFならオーバーフロー
  437.  
  438. ;.dの処理
  439. calcfex_size_double:
  440.     moveq.l    #52,d6            ;小数点以下52ビットまで(53ビット目を0捨1入する)
  441.     move.w    d0,d7
  442.     and.w    #$7FFF,d7
  443.     sub.w    #$3FFF-$3FE,d7
  444.     bpl    calcfex_size_double_0
  445.     add.w    d7,d6            ;非正規化数の場合はビット数を減らす
  446.                     ;非正規化数以下ならば負数が指定される
  447. calcfex_size_double_0:
  448.     bsr    calcfex_rn
  449.     move.w    d0,d6
  450.     and.w    #$7FFF,d6
  451.     cmp.w    #$3FFF+$3FF,d6
  452.     bhi    calcfex_size_real_inf
  453.     rts                ;非正規化数以下はcalcfex_rnで0になっており,
  454.                     ;0捨1入で指数部が減ることはないので,
  455.                     ;ここではアンダーフローや0をチェックしなくてよい
  456.  
  457. ;.sの処理
  458. calcfex_size_single:
  459.     moveq.l    #23,d6            ;小数点以下23ビットまで(24ビット目を0捨1入する)
  460.     move.w    d0,d7
  461.     and.w    #$7FFF,d7
  462.     sub.w    #$3FFF-$7E,d7
  463.     bpl    calcfex_size_single_0
  464.     add.w    d7,d6            ;非正規化数の場合はビット数を減らす
  465.                     ;非正規化数以下ならば負数が指定される
  466. calcfex_size_single_0:
  467.     bsr    calcfex_rn
  468.     move.w    d0,d6
  469.     and.w    #$7FFF,d6
  470.     cmp.w    #$3FFF+$7F,d6
  471.     bhi    calcfex_size_real_inf
  472.     rts                ;非正規化数以下はcalcfex_rnで0になっており,
  473.                     ;0捨1入で指数部が減ることはないので,
  474.                     ;ここではアンダーフローや0をチェックしなくてよい
  475.  
  476. ;doubleやsingleへの変換でオーバーフローするとき
  477. ;エラーは出さない
  478. calcfex_size_real_inf:
  479.     or.w    #$7FFF,d0
  480.     moveq.l    #0,d1
  481.     moveq.l    #0,d2
  482.     rts
  483.  
  484. ;.pの処理
  485. calcfex_size_packed:
  486.     bsr    xtop
  487.     bra    ptox
  488.  
  489. ;拡張精度実数をRounding Nearestで丸める
  490. ;<d0.w:d1.l:d2.l:拡張精度実数
  491. ;<d6.w:仮数部の小数点以下何ビットのところで丸めるか
  492. ;    -1  0  1  2  28 29 30 31  32  33  34  60 61 62 ← d6.w
  493. ;      31 30 29 …  2  1  0  31  30  29  …  2  1  0
  494. ;     |         d1         ||            d2         |
  495. ;    整数ならば小数点の位置
  496. ;    この位置の右側から左側へ0捨1入する
  497. ;    この位置の右側が1000…のときは左の位が0になるように丸める
  498. ;>d0.w:d1.l:d2.l:結果
  499. ;?d6.l/d7.l
  500. calcfex_rn::
  501.     cmp.w    #$7FFF,d0
  502.     bge    calcfex_rn_done        ;INFとNANはそのまま
  503.     cmp.w    #$FFFF,d0
  504.     bcc    calcfex_rn_done        ;INFとNANはそのまま
  505.     cmp.w    #-1,d6            ;指数部が-1でも1に繰り上がることがある
  506.     blt    calcfex_rn_zero        ;d1がすべて0.25以下(非正規化数を含む)
  507.     moveq.l    #30,d7
  508.     sub.w    d6,d7
  509. ;d7=0.5のビット(0~31)
  510. ;    31  30  29  28  2 1 0 -1  -2  -3  -4  -30 -31 -32 ← d7.w
  511. ;      31  30  29  … 2 1 0  31  30  29  …   2   1   0
  512. ;     |            d1      ||            d2            |
  513.     bmi    calcfex_rn_1        ;0.5のビットがd2側にある
  514. ;0.5のビットがd1にある
  515. ;d7=0.5のビット(0~31)
  516.     moveq.l    #0,d6
  517.     bset.l    d7,d6            ;0.5のビット(0~31)
  518. ;d6=0.5のビットだけセット
  519.     btst.l    d7,d1            ;0.5のビットをテスト
  520.     bne    calcfex_rn_2        ;0.5のビットが立っている
  521. ;0.5のビットがd1側にあり0.5のビットが立っていないので切り捨てる
  522. ;d6=0.5のビットだけセット
  523.     moveq.l    #0,d2
  524. ;0.5のビットがd1側にあり小数部が0.5で1のビットが0なので切り捨てる
  525. ;繰り上げたが仮数部が溢れなかった
  526. ;d2=0
  527. ;d6=0.5のビットだけセット
  528. calcfex_rn_5:
  529.     neg.l    d6            ;0.5以上のマスク
  530.     add.l    d6,d6            ;1以上のマスク(0のことがある)
  531.     beq    calcfex_rn_zero
  532.     and.l    d6,d1
  533. calcfex_rn_done:
  534.     rts
  535.  
  536. ;0.5のビットがd2側にある
  537. ;d7=0.5のビット(0~31)
  538. ;    -1  -2  -3  -4  -30 -31 -32 ← d7.w
  539. ;      31  30  29  …   2   1   0
  540. ;     |            d2            |
  541. calcfex_rn_1:
  542.     add.w    #32,d7
  543. ;d7=0.5のビット(0~31)
  544. ;    31  30  29  28  2  1 0 ← d7.w
  545. ;      31  30  29  …  2 1 0
  546. ;     |            d2       |
  547.     bmi    calcfex_rn_done        ;0.5のビットがd2よりも右にあるので何もしない
  548. ;d7=0.5のビット(0~31)
  549.     moveq.l    #0,d6
  550.     bset.l    d7,d6            ;0.5のビットだけセット
  551. ;d6=0.5のビットだけセット
  552.     btst.l    d7,d2            ;0.5のビットをテスト
  553.     bne    calcfex_rn_12        ;0.5のビットが立っている
  554. ;0.5のビットがd2側にあり0.5のビットが立っていないので切り捨てる
  555. ;d6=0.5のビットだけセット
  556. calcfex_rn_15:
  557.     neg.l    d6            ;0.5以上のマスク
  558.     add.l    d6,d6            ;1以上のマスク(0のことがある)
  559.     and.l    d6,d2
  560.     rts
  561.  
  562. ;0またはアンダーフロー
  563. calcfex_rn_zero:
  564.     and.w    #$8000,d0        ;符号だけ残す
  565.     moveq.l    #0,d1
  566.     moveq.l    #0,d2
  567.     rts
  568.  
  569. ;0.5のビットがd1側にあり0.5のビットが立っている
  570. ;d6=0.5のビットだけセット
  571. ;d7=0.5のビット(0~31)
  572. calcfex_rn_2:
  573.     tst.l    d2
  574.     bne    calcfex_rn_3        ;小数部が0.5ではないので繰り上げる
  575. ;d2=0
  576.     subq.l    #1,d6            ;0.25以下のマスク
  577.     and.l    d1,d6            ;0.25以下のビットが立っているか
  578.     bne    calcfex_rn_7        ;小数部が0.5ではないので繰り上げる
  579. ;0.5のビットがd1側にあり小数部が0.5なので0.5の丸めを行う
  580.     moveq.l    #0,d6
  581.     bset.l    d7,d6            ;0.5のビットだけセット
  582. ;d6=0.5のビットだけセット
  583.     addq.b    #1,d7            ;1のビット(1~32)
  584. ;d7=1のビット(0~31)
  585.     cmp.b    #32,d7
  586.     beq    calcfex_rn_zero        ;1のビットがないので切り捨てたら0になる
  587.     btst.l    d7,d1            ;1のビットをテスト
  588.     bne    calcfex_rn_4        ;1のビットが1なので繰り上げる
  589. ;0.5のビットがd1側にあり小数部が0.5で1のビットが0なので切り捨てる
  590.     bra    calcfex_rn_5
  591.  
  592. ;0.5のビットがd2側にあり小数部が0.5で1のビットがd1側にある
  593. ;d7=32
  594. calcfex_rn_18:
  595.     btst.l    d7,d1            ;1のビットをテスト
  596.     bne    calcfex_rn_16        ;1のビットが1なので繰り上げる
  597. ;0.5のビットがd2側にあり小数部が0.5で1のビットがd1側にあり1のビットが0なので切り捨てる
  598.     moveq.l    #0,d2
  599.     rts
  600.  
  601. ;0.5のビットがd2側にあり0.5のビットが立っている
  602. ;d6=0.5のビットだけセット
  603. ;d7=0.5のビット(0~31)
  604. calcfex_rn_12:
  605.     subq.l    #1,d6            ;0.25以下のマスク
  606.     and.l    d2,d6            ;0.25以下のビットが立っているか
  607.     bne    calcfex_rn_17        ;小数部が0.5ではないので繰り上げる
  608. ;0.5のビットがd2側にあり小数部が0.5なので0.5の丸めを行う
  609.     moveq.l    #0,d6
  610.     bset.l    d7,d6            ;0.5のビットだけセット
  611. ;d6=0.5のビットだけセット
  612.     addq.b    #1,d7            ;1のビット(1~32)
  613. ;d7=1のビット(1~32)
  614.     cmp.b    #32,d7
  615.     beq    calcfex_rn_18        ;1のビットがd1側にある
  616.     btst.l    d7,d2            ;1のビットをテスト
  617.     bne    calcfex_rn_14        ;1のビットが1なので繰り上げる
  618.     bra    calcfex_rn_15
  619.  
  620. ;0.5のビットがd2側にあり0.5のビットが立っているが小数部が0.5ではないので繰り上げる
  621. calcfex_rn_17:
  622.     moveq.l    #0,d6
  623.     bset.l    d7,d6            ;0.5のビットだけセット
  624. ;0.5のビットがd2側にあり小数部が0.5で1のビットが立っているので繰り上げる
  625. ;d6=0.5のビットだけセット
  626. calcfex_rn_14:
  627.     add.l    d6,d2            ;繰り上げる
  628.     bcc    calcfex_rn_15
  629. ;0.5のビットがd2側にあり繰り上げたらd2が溢れた
  630. ;0.5のビットがd2側にあり小数部が0.5で1のビットがd1側にあり1のビットが立っているので繰り上げる
  631. calcfex_rn_16:
  632.     moveq.l    #1,d6
  633. ;0.5のビットがd1側にあり0.5のビットが立っているが小数部が0.5ではないので繰り上げる
  634. ;d6=0.5のビットだけセット
  635. calcfex_rn_3:
  636.     moveq.l    #0,d2
  637.     bra    calcfex_rn_4
  638.  
  639. ;0.5のビットがd1側にあり0.5のビットが立っているが小数部が0.5ではないので繰り上げる
  640. ;d2=0
  641. ;d7=0.5のビット(0~31)
  642. calcfex_rn_7:
  643.     moveq.l    #0,d6
  644.     bset.l    d7,d6            ;0.5のビットだけセット
  645. ;0.5のビットがd1側にあり小数部が0.5で1のビットが1なので繰り上げる
  646. ;d2=0
  647. ;d6=0.5のビットだけセット
  648. calcfex_rn_4:
  649.     add.l    d6,d1            ;繰り上げる
  650.     bcc    calcfex_rn_5        ;仮数部が溢れなかった
  651. ;0.5のビットがd1側にあり繰り上げたら仮数部が溢れた
  652. ;d2=0
  653.     addq.w    #1,d0            ;INFやNANは最初に除いてあるので,
  654.                     ;指数部が溢れることはない
  655.     cmp.w    #$7FFF,d0
  656.     beq    calcfex_rn_overflow    ;オーバーフローした
  657.     cmp.w    #$FFFF,d0
  658.     beq    calcfex_rn_overflow    ;オーバーフローした
  659.     moveq.l    #1,d1            ;仮数部は%1000…になる
  660.     ror.l    #1,d1
  661.     rts
  662.  
  663. ;オーバーフローした
  664. ;d0=$7FFFまたは$FFFF
  665. ;d2=0
  666. calcfex_rn_overflow:
  667.     moveq.l    #0,d1
  668.     rts
  669.  
  670. ;----------------------------------------------------------------
  671. ;単項整数演算
  672. ;<d6.b:演算子番号
  673. ;<a1.l:演算子の右側の式を計算するルーチンのアドレス
  674. calcfex_intop1:
  675.     addq.l    #2,a0
  676.     move.b    d6,-(sp)
  677.     jsr    (a1)
  678.     bsr    xtol_overflow_check
  679.     bra    calcfex_intop0
  680.  
  681. ;二項整数演算
  682. ;<d6.b:演算子番号
  683. ;<a1.l:演算子の右側の式を計算するルーチンのアドレス
  684. calcfex_intop2:
  685.     addq.l    #2,a0
  686.     bsr    xtol_overflow_check
  687.     move.b    d6,-(sp)
  688.     move.l    d0,-(sp)        ;披演算数
  689.     jsr    (a1)
  690.     bsr    xtol_overflow_check
  691.     move.l    d0,d1            ;演算数
  692.     move.l    (sp)+,d0
  693. calcfex_intop0:
  694.     clr.w    d6
  695.     move.b    (sp)+,d6
  696.     bsr    calcfex_opjmp
  697.     bra    ltox
  698.  
  699. xtol_overflow_check:
  700.     bsr    xtol
  701.     tst.w    d1
  702.     bmi    overflowerr
  703.     rts
  704.  
  705. ;二項演算
  706. ;<d6.b:演算子番号
  707. ;<a1.l:演算子の右側の式を計算するルーチンのアドレス
  708. calcfex_op2:
  709.     addq.l    #2,a0
  710.     move.b    d6,-(sp)
  711.     movem.l    d0-d2,-(sp)
  712.     jsr    (a1)
  713.     move.l    d0,d3
  714.     move.l    d1,d4
  715.     move.l    d2,d5
  716.     movem.l    (sp)+,d0-d2
  717.     clr.w    d6
  718.     move.b    (sp)+,d6
  719. calcfex_opjmp:
  720.     add.w    d6,d6            ;演算子番号*2
  721.     move.w    (fexjp_tbl-2*OP_NOT,pc,d6.w),d6
  722.     jmp    (fexjp_tbl,pc,d6.w)
  723.  
  724. fexjp_tbl:
  725.     .dc.w    fex_not-fexjp_tbl    ;.not.
  726.     .dc.w    fex_high-fexjp_tbl    ;.high.
  727.     .dc.w    fex_low-fexjp_tbl    ;.low.
  728.     .dc.w    fex_highw-fexjp_tbl    ;.highw.
  729.     .dc.w    fex_loww-fexjp_tbl    ;.loww.
  730.     .dc.w    fex_nul-fexjp_tbl    ;.nul.
  731.     .dc.w    xmul-fexjp_tbl        ;*    (二項演算子)
  732.     .dc.w    xdiv-fexjp_tbl        ;/
  733.     .dc.w    -1            ;.mod.
  734.     .dc.w    fex_shr-fexjp_tbl    ;.shr.(>>)
  735.     .dc.w    fex_shl-fexjp_tbl    ;.shl.(<<)
  736.     .dc.w    fex_asr-fexjp_tbl    ;.asr.
  737.     .dc.w    xsub-fexjp_tbl        ;-
  738.     .dc.w    xadd-fexjp_tbl        ;+
  739.     .dc.w    fex_eq-fexjp_tbl    ;.eq.(=,==)
  740.     .dc.w    fex_ne-fexjp_tbl    ;.ne.(<>,!=)
  741.     .dc.w    fex_lt-fexjp_tbl    ;.lt.(<)
  742.     .dc.w    fex_le-fexjp_tbl    ;.le.(<=)
  743.     .dc.w    fex_gt-fexjp_tbl    ;.gt.(>)
  744.     .dc.w    fex_ge-fexjp_tbl    ;.ge.(>=)
  745.     .dc.w    fex_lt-fexjp_tbl    ;.slt.
  746.     .dc.w    fex_le-fexjp_tbl    ;.sle.
  747.     .dc.w    fex_gt-fexjp_tbl    ;.sgt.
  748.     .dc.w    fex_ge-fexjp_tbl    ;.sge.
  749.     .dc.w    fex_and-fexjp_tbl    ;.and.(&)
  750.     .dc.w    fex_xor-fexjp_tbl    ;.xor.(^)
  751.     .dc.w    fex_or-fexjp_tbl    ;.or.(|)
  752.     .dc.w    fex_notb-fexjp_tbl    ;.notb.
  753.     .dc.w    fex_notw-fexjp_tbl    ;.notw.
  754.  
  755. fex_not:
  756.     not.l    d0
  757.     rts
  758.  
  759. fex_notb:
  760.     not.b    d0
  761.     bra    fex_low
  762.  
  763. fex_high:
  764.     lsr.l    #8,d0
  765. fex_low:
  766.     and.l    #$000000FF,d0
  767.     rts
  768.  
  769. fex_notw:
  770.     not.w    d0
  771. fex_loww:
  772.     swap.w    d0
  773. fex_highw:
  774.     clr.w    d0
  775.     swap.w    d0
  776.     rts
  777.  
  778. fex_nul:
  779.     moveq.l    #0,d0
  780.     rts
  781.  
  782. fex_shr:
  783.     lsr.l    d1,d0
  784.     rts
  785.  
  786. fex_shl:
  787.     lsl.l    d1,d0
  788.     rts
  789.  
  790. fex_asr:
  791.     asr.l    d1,d0
  792.     rts
  793.  
  794. fex_eq:
  795.     bsr    fex_cmp
  796.     beq    fex_true
  797. fex_false:
  798.     moveq.l    #0,d0            ;d0:d1:d2 = 0.0
  799.     moveq.l    #0,d1
  800.     moveq.l    #0,d2
  801.     rts
  802.  
  803. fex_true:
  804.     move.w    #$BFFF,d0        ;d0:d1:d2 = -1.0
  805.     move.l    #$80000000,d1
  806.     moveq.l    #0,d2
  807.     rts
  808.  
  809. fex_ne:
  810.     bsr    fex_cmp
  811.     bne    fex_true
  812.     bra    fex_false
  813.  
  814. fex_lt:
  815.     bsr    fex_cmp
  816.     blo    fex_true
  817.     bra    fex_false
  818.  
  819. fex_le:
  820.     bsr    fex_cmp
  821.     bls    fex_true
  822.     bra    fex_false
  823.  
  824. fex_gt:
  825.     bsr    fex_cmp
  826.     bhi    fex_true
  827.     bra    fex_false
  828.  
  829. fex_ge:
  830.     bsr    fex_cmp
  831.     bhs    fex_true
  832.     bra    fex_false
  833.  
  834. fex_cmp:
  835.     ext.l    d0            ;符号を上位ワードへ
  836.     ext.l    d3
  837.     move.w    #$7FFF,d6
  838.     and.w    d6,d0
  839.     beq    fex_cmp_za        ;(0または非正規化数)-?
  840. fex_cmp1:
  841.     cmp.w    d6,d0
  842.     beq    fex_cmp_nia        ;(INFまたはNAN)-?
  843. fex_cmp2:
  844.     and.w    d6,d3
  845.     beq    fex_cmp_zb        ;?-(0または非正規化数)
  846. fex_cmp3:
  847.     cmp.w    d6,d3
  848.     beq    fex_cmp_nib        ;?-(INFまたはNAN)
  849. fex_cmp4:
  850. ;指数部の符号を除去する
  851. ;非正規化数は一時的に正規化されているので+$3FFFでは足りない
  852. ;INFが$7FFFになっているので+$8000よりも大きな数を加えてはならない
  853.     add.w    #$8000,d0
  854.     add.w    #$8000,d3
  855.     tst.l    d0
  856.     bmi    fex_cmp6        ;負数-?
  857. ;正数-?
  858.     tst.l    d3
  859.     bmi    fex_cmp7        ;正数-負数
  860. ;正数-正数
  861.     cmp.w    d3,d0
  862.     bne    fex_cmp59
  863.     cmp.l    d4,d1
  864.     bne    fex_cmp59
  865.     cmp.l    d5,d2
  866. fex_cmp59:
  867.     rts
  868.  
  869. ;負数-?
  870. fex_cmp6:
  871.     tst.l    d3
  872.     bpl    fex_cmp8        ;負数-正数
  873. ;負数-負数
  874.     cmp.w    d0,d3
  875.     bne    fex_cmp69
  876.     cmp.l    d1,d4
  877.     bne    fex_cmp69
  878.     cmp.l    d2,d5
  879. fex_cmp69:
  880.     rts
  881.  
  882. ;正数-負数
  883. fex_cmp7:
  884.     moveq.l    #1,d0
  885.     rts
  886.  
  887. ;負数-正数
  888. fex_cmp8:
  889.     moveq.l    #-1,d0
  890.     rts
  891.  
  892. fex_cmp_za:                ;(0または非正規化数)-?
  893.     move.l    d1,d6
  894.     or.l    d2,d6
  895.     beq    fex_cmp1        ;0-?
  896. fex_cmp_za1:                ;非正規化数を一時的に正規化する
  897.     tst.l    d1
  898.     bmi    fex_cmp1
  899.     subq.w    #1,d0
  900.     add.l    d2,d2
  901.     addx.l    d1,d1
  902.     bra    fex_cmp_za1
  903.  
  904. fex_cmp_nia:                ;(INFまたはNAN)-?
  905.     add.l    d1,d1
  906.     or.l    d2,d1
  907.     bne    fex_cmp_nan        ;NAN-?
  908.     cmp.l    d3,d0            ;符号つきで比較
  909.     bne    fex_cmp2        ;INF-?
  910.     bra    fex_cmp_nan        ;INF-INF=NANまたは(-INF)-(-INF)=NAN
  911.  
  912. fex_cmp_zb:                ;?-(0または非正規化数)
  913.     move.l    d4,d6
  914.     or.l    d5,d6
  915.     beq    fex_cmp3        ;?-0
  916. fex_cmp_zb1:                ;非正規化数を一時的に正規化する
  917.     tst.l    d4
  918.     bmi    fex_cmp3
  919.     subq.w    #1,d0
  920.     add.l    d5,d5
  921.     addx.l    d4,d4
  922.     bra    fex_cmp_zb1
  923.  
  924. fex_cmp_nib:                ;?-(INFまたはNAN)
  925.     add.l    d4,d4
  926.     or.l    d5,d4
  927.     beq    fex_cmp4        ;?-INF
  928. ;    bra    fex_cmp_nan        ;?-NAN
  929. fex_cmp_nan:
  930.     move.w    #$7FFF,d0        ;比較不能なのでNANを返す
  931.     moveq.l    #-1,d1
  932.     moveq.l    #-1,d2
  933.     addq.l    #4,sp            ;true/falseを破棄
  934.     rts
  935.  
  936. fex_and:
  937.     and.l    d1,d0
  938.     rts
  939.  
  940. fex_xor:
  941.     eor.l    d1,d0
  942.     rts
  943.  
  944. fex_or:
  945.     or.l    d1,d0
  946.     rts
  947.  
  948. ;----------------------------------------------------------------
  949. ;    拡張精度実数演算ルーチン
  950. ;
  951. ;    d0: b31~b16    (未使用)
  952. ;        b15        = 仮数部符号
  953. ;        b14~b0    = 指数部
  954. ;    d1,d2        = 仮数部
  955. ;----------------------------------------------------------------
  956.  
  957. ;----------------------------------------------------------------
  958. ;    浮動小数文字列を拡張精度実数に変換する
  959. ;    in :a0 = 変換文字列へのポインタ
  960. ;    out:d0:d1:d2 = 結果(d0.l=-1ならエラー)
  961. strtox::
  962.     move.l    a0,-(sp)
  963.     movem.l    d3-d7/a1-a2,-(sp)
  964.     bsr    getsign            ;仮数部符号を得る
  965.     move.w    d7,-(sp)
  966.     moveq.l    #0,d6
  967.     cmpi.b    #'.',(a0)
  968.     bne    strtox1
  969.     addq.l    #1,a0
  970.     moveq.l    #-1,d6
  971.     moveq.l    #$20,d7
  972.     or.b    (a0),d7
  973.     cmp.b    #'e',d7
  974.     bne    strtox1
  975.     moveq.l    #0,d0
  976.     moveq.l    #0,d1
  977.     moveq.l    #0,d2
  978.     bra    strtox8
  979.  
  980. strtox1:
  981.     bsr    getdigit        ;最初の1桁を得る
  982.     bmi    strtox99        ;数値でなければエラー
  983.     move.l    d7,d0
  984.     bsr    ltox
  985.     bra    strtox3
  986.  
  987. strtox2:
  988.     move.w    #$4002,d3
  989.     move.l    #$A0000000,d4
  990.     moveq.l    #0,d5            ;d3:d4:d5 = +10.0
  991.     bsr    xmul
  992.     move.w    d0,d3
  993.     move.l    d1,d4
  994.     move.l    d2,d5
  995.     move.l    d7,d0
  996.     bsr    ltox
  997.     bsr    xadd
  998.     tst.l    d6
  999.     bpl    strtox3
  1000.     subq.w    #1,d6
  1001. strtox3:
  1002.     bsr    getdigit
  1003.     bpl    strtox2
  1004.     move.b    (a0),d7
  1005.     cmp.b    #'.',d7
  1006.     bne    strtox4
  1007.     tst.l    d6
  1008.     bmi    strtox9            ;2つ目の小数点ならそこで終了する
  1009.     addq.l    #1,a0
  1010.     move.w    #-1,d6
  1011.     swap.w    d6
  1012.     bra    strtox3
  1013.  
  1014. strtox4:
  1015.     or.b    #$20,d7
  1016.     cmp.b    #'e',d7
  1017.     bne    strtox9            ;指数部はない
  1018. strtox8:
  1019.     addq.l    #1,a0
  1020.     bsr    getsign            ;指数部符号を得る
  1021.     move.w    d7,d3
  1022.     bsr    getdigit        ;最初の1桁を得る
  1023.     bmi    strtox99        ;数値でなければエラー
  1024.     move.w    d7,d4
  1025.     bra    strtox6
  1026.  
  1027. strtox5:
  1028.     add.w    d4,d4
  1029.     move.w    d4,d5
  1030.     add.w    d4,d4
  1031.     add.w    d4,d4
  1032.     add.w    d5,d4            ;d4.l *= 10
  1033.     add.w    d7,d4
  1034. strtox6:
  1035.     bsr    getdigit
  1036.     bpl    strtox5
  1037.     tst.w    d3
  1038.     bmi    strtox7
  1039.     add.w    d4,d6            ;指数部は正
  1040.     bra    strtox9
  1041.  
  1042. strtox7:
  1043.     sub.w    d4,d6            ;指数部は負
  1044.  
  1045. strtox9:
  1046.     movem.l    d0-d2,-(sp)
  1047.     move.w    #$3FFF,d0
  1048.     move.l    #$80000000,d1
  1049.     moveq.l    #0,d2            ;d0:d1:d2 = 1.0
  1050.     moveq.l    #13-1,d7
  1051.     tst.w    d6
  1052.     bmi    strtox_m
  1053.                     ;10進指数から10^nを得る
  1054. strtox_p:                ;正の指数(1.0以上)の場合
  1055.     lea.l    (decexptblp,pc),a1
  1056.     lea.l    (decmantblp,pc),a2
  1057.     rol.w    #3-1,d6
  1058. strtox_p1:
  1059.     move.w    (a1)+,d3
  1060.     movem.l    (a2)+,d4-d5
  1061.     add.w    d6,d6
  1062.     bpl    strtox_p2
  1063.     bsr    xmul            ;10の累乗を掛ける
  1064. strtox_p2:
  1065.     dbra    d7,strtox_p1
  1066.     bra    strtox10
  1067.  
  1068. strtox_m:                ;負の指数(1.0未満)の場合
  1069.     lea.l    (decexptblm,pc),a1
  1070.     lea.l    (decmantblm,pc),a2
  1071.     neg.w    d6
  1072.     rol.w    #3-1,d6
  1073. strtox_m1:
  1074.     move.w    (a1)+,d3
  1075.     movem.l    (a2)+,d4-d5
  1076.     add.w    d6,d6
  1077.     bpl    strtox_m2
  1078.     bsr    xmul            ;10の累乗を掛ける
  1079. strtox_m2:
  1080.     dbra    d7,strtox_m1
  1081.  
  1082. strtox10:
  1083.     movem.l    (sp)+,d3-d5        ;仮数部
  1084.     bsr    xmul            ;仮数部×(10^指数部)
  1085.  
  1086.     tst.w    (sp)+
  1087.     bpl    strtox11
  1088.     or.w    #$8000,d0        ;仮数部符号は負
  1089. strtox11:
  1090.     swap.w    d0
  1091.     clr.w    d0
  1092.     swap.w    d0
  1093.     movem.l    (sp)+,d3-d7/a1-a2
  1094.     addq.l    #4,sp            ;スタック補正
  1095.     rts
  1096.  
  1097. strtox99:                ;エラーの場合
  1098.     moveq.l    #-1,d0
  1099.     addq.l    #2,sp            ;スタック補正
  1100.     movem.l    (sp)+,d3-d7/a1-a2
  1101.     movea.l    (sp)+,a0        ;ポインタを元に戻す
  1102.     rts
  1103.  
  1104. ;----------------------------------------------------------------
  1105. ;    符号を得る
  1106. getsign:
  1107.     move.b    (a0),d7
  1108.     cmp.b    #'-',d7
  1109.     beq    getsignn
  1110.     cmp.b    #'+',d7
  1111.     bne    getsignp
  1112.     addq.l    #1,a0
  1113. getsignp:
  1114.     moveq.l    #0,d7
  1115.     rts
  1116.  
  1117. getsignn:
  1118.     addq.l    #1,a0
  1119.     moveq.l    #-1,d7
  1120.     rts
  1121.  
  1122. ;----------------------------------------------------------------
  1123. ;    数字を1桁得る
  1124. getdigit:
  1125.     moveq.l    #0,d7
  1126.     move.b    (a0)+,d7
  1127.     cmp.b    #'_',d7
  1128.     beq    getdigit
  1129.     sub.b    #'0',d7
  1130.     bcs    getdigit9
  1131.     cmp.b    #9,d7
  1132.     bhi    getdigit9
  1133.     tst.w    d7
  1134.     rts
  1135.  
  1136. getdigit9:
  1137.     subq.l    #1,a0
  1138.     moveq.l    #-1,d7
  1139.     rts
  1140.  
  1141. ;----------------------------------------------------------------
  1142. ;    符号を反転する
  1143. ;    in :d0:d1:d2 = 拡張精度実数値
  1144. ;    out:d0:d1:d2 = 結果
  1145. xneg::
  1146.     bchg.l    #15,d0            ;仮数部符号を反転する
  1147.     rts
  1148.  
  1149. ;----------------------------------------------------------------
  1150. ;    2数を比較する(A-B)
  1151. ;    in :d0:d1:d2 = 拡張精度実数値A
  1152. ;        d3:d4:d5 = 拡張精度実数値B
  1153. ;    out:ccr = 結果
  1154. xcmp::
  1155.     move.l    d6,-(sp)
  1156.     tst.w    d0
  1157.     bmi    xcmp_m            ;A<0のとき
  1158.     tst.w    d3
  1159.     bmi    xcmp_hiz
  1160.     cmp.w    d3,d0
  1161.     bcs    xcmp_lo
  1162.     bhi    xcmp_hi
  1163.     cmp.l    d4,d1
  1164.     bcs    xcmp_lo
  1165.     bhi    xcmp_hi
  1166.     cmp.l    d5,d2
  1167.     bcs    xcmp_lo
  1168.     bhi    xcmp_hi
  1169.     move.w    #$0004,ccr        ;A=B
  1170.     move.l    (sp)+,d6
  1171.     rts
  1172.  
  1173. xcmp_m:                    ;A>0のとき
  1174.     tst.w    d3
  1175.     bpl    xcmp_loz
  1176.     cmp.w    d3,d0
  1177.     bcs    xcmp_hi
  1178.     bhi    xcmp_lo
  1179.     cmp.l    d4,d1
  1180.     bcs    xcmp_hi
  1181.     bhi    xcmp_lo
  1182.     cmp.l    d5,d2
  1183.     bcs    xcmp_hi
  1184.     bhi    xcmp_lo
  1185. xcmp_eq:
  1186.     move.w    #$0004,ccr        ;A=B
  1187.     move.l    (sp)+,d6
  1188.     rts
  1189.  
  1190. xcmp_hiz:
  1191.     move.w    d0,d6
  1192.     or.w    d3,d6
  1193.     and.w    #$7FFF,d6
  1194.     bne    xcmp_hi
  1195.     move.l    d1,d6
  1196.     or.l    d2,d6
  1197.     or.l    d4,d6
  1198.     or.l    d5,d6
  1199.     beq    xcmp_eq            ;-0.0 == +0.0
  1200. xcmp_hi:
  1201.     move.w    #$0000,ccr        ;A>B
  1202.     move.l    (sp)+,d6
  1203.     rts
  1204.  
  1205. xcmp_loz:
  1206.     move.w    d0,d6
  1207.     or.w    d3,d6
  1208.     and.w    #$7FFF,d6
  1209.     bne    xcmp_lo
  1210.     move.l    d1,d6
  1211.     or.l    d2,d6
  1212.     or.l    d4,d6
  1213.     or.l    d5,d6
  1214.     beq    xcmp_eq            ;-0.0 == +0.0
  1215. xcmp_lo:
  1216.     move.w    #$0009,ccr        ;A<B
  1217.     move.l    (sp)+,d6
  1218.     rts
  1219.  
  1220. ;----------------------------------------------------------------
  1221. ;    2数を減算する(A=A-B)
  1222. ;    in :d0:d1:d2 = 拡張精度実数値A
  1223. ;        d3:d4:d5 = 拡張精度実数値B
  1224. ;    out:d0:d1:d2 = 結果
  1225. xsub::
  1226.     movem.l    d3-d7,-(sp)
  1227.     bchg.l    #15,d3            ;仮数部符号を反転する
  1228.     bra    xadd0            ;A-B = A+(-B)
  1229.  
  1230. ;----------------------------------------------------------------
  1231. ;    2数を加算する(A=A+B)
  1232. ;    in :d0:d1:d2 = 拡張精度実数値A
  1233. ;        d3:d4:d5 = 拡張精度実数値B
  1234. ;    out:d0:d1:d2 = 結果
  1235. xadd::
  1236.     movem.l    d3-d7,-(sp)
  1237. xadd0:
  1238.     move.w    d0,d6
  1239.     eor.w    d3,d6
  1240.     swap.w    d6
  1241.     move.w    d0,d6
  1242.     move.w    #$7FFF,d7
  1243.     and.w    d7,d0
  1244.     beq    xadd_za            ;A=0 or 非正規化数
  1245.     cmp.w    d7,d0
  1246.     beq    xadd_nia        ;A=NAN or ±INF
  1247. xadd1:
  1248.     and.w    d7,d3
  1249.     beq    xadd_zb            ;B=0 or 非正規化数
  1250.     cmp.w    d7,d3
  1251.     beq    xadd_nib        ;B=NAN or ±INF
  1252. xadd2:
  1253.     tst.l    d6
  1254.     bmi    xadd_s            ;AとBの符号が異なる(減算)
  1255.  
  1256. ;----------------------------------------------------------------
  1257. ;    符号の同じ数の加算
  1258. xadd_a:
  1259.     cmp.w    d3,d0
  1260.     beq    xadd_ae            ;AとBの指数が同じ
  1261.     bgt    xadd_a1            ;A>Bのとき(一時正規化数のため符号付き比較)
  1262.     exg.l    d0,d3            ;A<Bなら2数を交換する
  1263.     exg.l    d1,d4
  1264.     exg.l    d2,d5
  1265. xadd_a1:
  1266.     add.l    d2,d2            ;A <<= 1 (仮数部整数ビットを削除)
  1267.     addx.l    d1,d1
  1268.     move.w    d0,d7
  1269.     sub.w    d3,d7
  1270.     subq.w    #2,d7
  1271.     bcs    xadd_a5            ;Aが1桁大きい
  1272.     cmp.w    #64-1,d7
  1273.     bcc    xadd_a6            ;64桁以上大きければAをそのまま返す
  1274. xadd_a2:                ;Aと小数点位置を合わせる
  1275.     lsr.l    #1,d4
  1276.     roxr.l    #1,d5
  1277.     dbra    d7,xadd_a2
  1278. xadd_a5:
  1279.     move.w    d5,d3
  1280.     lsr.w    #1,d3            ;最下位ビットを取り出す(→X)
  1281.     addx.l    d5,d2            ;A += B(Bの最下位ビットを丸める)
  1282.     addx.l    d4,d1
  1283.     bcc    xadd_a6            ;桁上がりしていない
  1284.     addq.w    #1,d0            ;指数が1桁増える
  1285.     cmp.w    #$7FFF,d0
  1286.     beq    xadd_infa        ;オーバーフロー
  1287.     moveq.l    #0,d3
  1288.     lsr.l    #1,d1            ;A /= 2
  1289.     roxr.l    #1,d2
  1290.     move.w    d2,d3            ;最下位ビットを丸める
  1291.     and.w    #$0001,d3
  1292.     addx.l    d3,d2
  1293.     moveq.l    #0,d3
  1294.     addx.l    d3,d1
  1295. xadd_a6:
  1296.     move.w    #$0010,ccr        ;X=1
  1297.     roxr.l    #1,d1            ;結果の整数ビットを付け加える
  1298.     roxr.l    #1,d2            ;(シフト前の最下位ビットは必ず0)
  1299.     bra    xadd_ae0        ;一時正規化数なら正規化数に戻してAを返す
  1300.  
  1301. xadd_ae:                ;AとBの指数が同じとき
  1302.     addq.w    #1,d0            ;指数が1桁増える
  1303.     cmp.w    #$7FFF,d0
  1304.     beq    xadd_infa        ;オーバーフロー
  1305.     add.l    d5,d2            ;A += B
  1306.     addx.l    d4,d1            ;(整数ビットが立っているので必ずキャリー)
  1307.     roxr.l    #1,d1            ;A /= 2
  1308.     roxr.l    #1,d2
  1309.     moveq.l    #0,d3            ;丸めを行う
  1310.     roxl.w    #1,d3            ;シフトではみだした最下位ビット
  1311.     add.l    d3,d2            ;最下位ビットを切り上げる(0捨1入)
  1312.     moveq.l    #0,d3
  1313.     addx.l    d3,d1
  1314. xadd_ae0:
  1315.     tst.w    d0
  1316.     bpl    xadd_ae5        ;結果が正規化数の場合
  1317. xadd_ae1:                ;一時正規化数を非正規化数に戻す
  1318.     addq.w    #1,d0
  1319.     lsr.l    #1,d1
  1320.     roxr.l    #1,d2
  1321.     tst.w    d0
  1322.     bne    xadd_ae1
  1323.     moveq.l    #0,d3            ;丸めを行う
  1324.     roxl.w    #1,d3            ;シフトではみだした最下位ビット
  1325.     add.l    d3,d2            ;最下位ビットを切り上げる(0捨1入)
  1326.     moveq.l    #0,d3
  1327.     addx.l    d3,d1
  1328. xadd_ae5:
  1329.     tst.w    d6            ;Aと同じ符号
  1330.     bpl    xadd_ae9
  1331.     or.w    #$8000,d0
  1332. xadd_ae9:
  1333.     movem.l    (sp)+,d3-d7
  1334.     rts
  1335.  
  1336. xadd_infa:                ;INFになった(Aと同じ符号)
  1337.     tst.w    d6
  1338.     bpl    xadd_infa1
  1339.     or.w    #$8000,d0
  1340. xadd_infa1:
  1341.     moveq.l    #0,d1
  1342.     moveq.l    #0,d2
  1343.     movem.l    (sp)+,d3-d7
  1344.     rts
  1345.  
  1346. ;----------------------------------------------------------------
  1347. ;    符号の異なる数の加算
  1348. xadd_s:
  1349.     cmp.w    d3,d0
  1350.     beq    xadd_se            ;AとBの指数が同じ
  1351.     bgt    xadd_s1            ;A>Bのとき(一時正規化数のため符号付き比較)
  1352.     exg.l    d0,d3            ;A<Bなら2数を交換して符号を反転する
  1353.     exg.l    d1,d4
  1354.     exg.l    d2,d5
  1355.     not.w    d6
  1356. xadd_s1:
  1357.     add.l    d2,d2            ;A <<= 1    (仮数部整数ビットを削除)
  1358.     addx.l    d1,d1
  1359.     move.w    d0,d7
  1360.     sub.w    d3,d7
  1361.     subq.w    #2,d7
  1362.     bcs    xadd_s5            ;Aが1桁大きい
  1363.     cmp.w    #64-1,d7
  1364.     bcc    xadd_s6            ;64桁以上大きければAをそのまま返す
  1365. xadd_s2:                ;Aと小数点位置を合わせる
  1366.     lsr.l    #1,d4
  1367.     roxr.l    #1,d5
  1368.     dbra    d7,xadd_s2
  1369. xadd_s5:
  1370.     move.w    d5,d3
  1371.     lsr.w    #1,d3            ;最下位ビットを取り出す(→X)
  1372.     subx.l    d5,d2            ;A -= B(Bの最下位ビットを丸める)
  1373.     subx.l    d4,d1
  1374.     bcc    xadd_s6            ;桁下がりしていない
  1375.     subq.w    #1,d0            ;指数が1桁減る
  1376.     bra    xadd_se1        ;一時正規化数なら正規化数に戻してAを返す
  1377.  
  1378. xadd_s6:
  1379.     move.w    #$0010,ccr        ;X=1
  1380.     roxr.l    #1,d1            ;結果の整数ビットを付け加える
  1381.     roxr.l    #1,d2            ;(シフト前の最下位ビットは必ず0)
  1382.     bra    xadd_se1        ;一時正規化数なら正規化数に戻してAを返す
  1383.  
  1384. xadd_se:                ;AとBの指数が同じとき
  1385.     sub.l    d5,d2            ;A -= B
  1386.     subx.l    d4,d1
  1387.     bhi    xadd_se1
  1388.     neg.l    d2            ;A<Bだったので符号を反転する
  1389.     negx.l    d1
  1390.     beq    xadd_sez        ;結果が0になった
  1391.     not.w    d6
  1392. xadd_se1:
  1393.     tst.w    d0
  1394.     bmi    xadd_ae1        ;一時正規化数を非正規化数に戻す
  1395.     beq    xadd_se5        ;すでに正規化/非正規化されている
  1396.     tst.l    d1
  1397.     bmi    xadd_se5        ;正規化されている
  1398. xadd_se2:
  1399.     subq.w    #1,d0
  1400.     add.l    d2,d2
  1401.     addx.l    d1,d1
  1402.     bmi    xadd_se5        ;正規化が終了した
  1403.     subq.w    #1,d3
  1404.     bne    xadd_se2        ;指数部が0になったら正規化を中断する
  1405. xadd_se5:
  1406.     tst.w    d6            ;Aと同じ符号
  1407.     bpl    xadd_se9
  1408.     or.w    #$8000,d0
  1409. xadd_se9:
  1410.     movem.l    (sp)+,d3-d7
  1411.     rts
  1412.  
  1413. xadd_sez:                ;結果が0になった
  1414.     moveq.l    #0,d0            ;+0.0
  1415.     movem.l    (sp)+,d3-d7
  1416.     rts
  1417.  
  1418. xadd_za:                ;A=0 or 非正規化数
  1419.     move.l    d1,d7
  1420.     or.l    d2,d7
  1421.     bne    xadd_za1
  1422.     move.l    d3,d0            ;0+B = B
  1423.     move.l    d4,d1
  1424.     move.l    d5,d2
  1425.     move.w    #$7FFF,d7
  1426.     and.w    d7,d3
  1427.     beq    xadd_z            ;0+0 or 非正規化数
  1428.     cmp.w    d7,d3
  1429.     beq    xadd_nib        ;0+NAN or 0+INF
  1430.     movem.l    (sp)+,d3-d7
  1431.     rts
  1432.  
  1433. xadd_z:
  1434.     or.l    d4,d3
  1435.     beq    xadd_z9            ;0+0
  1436.     move.w    d6,d0            ;0+非正規化数
  1437.     swap.w    d6
  1438.     eor.w    d6,d0
  1439.     and.w    #$8000,d0        ;Bの符号
  1440.     movem.l    (sp)+,d3-d7
  1441.     rts
  1442.  
  1443. xadd_z9:                ;0+0
  1444.     move.w    d6,d0            ;(-0.0)+(-0.0)=-0.0
  1445.     swap.w    d6            ;それ以外は +0.0
  1446.     not.w    d6
  1447.     and.w    d6,d0
  1448.     and.w    #$8000,d0
  1449.     movem.l    (sp)+,d3-d7
  1450.     rts
  1451.  
  1452. xadd_za1:                ;非正規化数を一時的に正規化する
  1453.     move.w    #$7FFF,d7
  1454. xadd_za2:
  1455.     tst.l    d1
  1456.     bmi    xadd1
  1457.     subq.w    #1,d0
  1458.     add.l    d2,d2
  1459.     addx.l    d1,d1
  1460.     bra    xadd_za2
  1461.  
  1462. xadd_nia:                ;A=NAN or ±INF
  1463.     add.l    d1,d1
  1464.     or.l    d2,d1
  1465.     bne    xadd_n            ;仮数部が0でないならNAN
  1466.     and.w    d7,d3            ;Bの指数
  1467.     cmp.w    d7,d3
  1468.     bne    xadd_ni9        ;INF+B = INF
  1469.     add.l    d4,d4
  1470.     or.l    d5,d4
  1471.     bne    xadd_n            ;仮数部が0でないならNAN
  1472.     tst.l    d6
  1473.     bmi    xadd_n            ;INF-INF = NAN    (AとBの符号が異なる)
  1474. xadd_ni9:                ;Aをそのまま返す
  1475.     move.w    d6,d0
  1476.     movem.l    (sp)+,d3-d7
  1477.     rts
  1478.  
  1479. xadd_zb:                ;B=0 or 非正規化数
  1480.     move.l    d4,d7
  1481.     or.l    d5,d7
  1482.     beq    xadd_ae0        ;A+0 = Aを返す(一時正規化数なら非正規仮数に戻す)
  1483. xadd_zb1:                ;非正規化数を一時的に正規化する
  1484.     tst.l    d4
  1485.     bmi    xadd2
  1486.     subq.w    #1,d3
  1487.     add.l    d5,d5
  1488.     addx.l    d4,d4
  1489.     bra    xadd_zb1
  1490.  
  1491. xadd_nib:                ;B=NAN or ±INF
  1492.     add.l    d4,d4
  1493.     or.l    d5,d4
  1494.     bne    xadd_n            ;仮数部が0でないならNAN
  1495.     move.l    (sp),d0            ;A+INF = INF (Bの符号)
  1496.     moveq.l    #0,d1
  1497.     moveq.l    #0,d2
  1498.     movem.l    (sp)+,d3-d7
  1499.     rts
  1500.  
  1501. xadd_n:                    ;NANを返す
  1502.     move.w    #$7FFF,d0
  1503.     moveq.l    #-1,d1
  1504.     moveq.l    #-1,d2
  1505.     movem.l    (sp)+,d3-d7
  1506.     rts
  1507.  
  1508. ;----------------------------------------------------------------
  1509. ;    2数を乗算する(A=A*B)
  1510. ;    in :d0:d1:d2 = 拡張精度実数値A
  1511. ;        d3:d4:d5 = 拡張精度実数値B
  1512. ;    out:d0:d1:d2 = 結果
  1513. xmul::
  1514.     movem.l    d3-d7,-(sp)
  1515.     move.w    d0,d6
  1516.     eor.w    d3,d6            ;結果の符号
  1517.     move.w    #$7FFF,d7
  1518.     and.w    d7,d0
  1519.     beq    xmul_za            ;A=0 or 非正規化数
  1520.     cmp.w    d7,d0
  1521.     beq    xmul_nia        ;A=NAN or ±INF
  1522. xmul1:
  1523.     and.w    d7,d3
  1524.     beq    xmul_zb            ;B=0 or 非正規化数
  1525.     cmp.w    d7,d3
  1526.     beq    xmul_nib        ;B=NAN or ±INF
  1527. xmul2:
  1528.     movem.w    d0/d3/d6,-(sp)        ;A1234 * B1234
  1529.  
  1530. ;            A1  A2  A3  A4
  1531. ;             × B1  B2  B3  B4
  1532. ;            -------------------
  1533. ;                    44H 44L
  1534. ;                34H 34L
  1535. ;            24H 24L
  1536. ;            14H 14L 43H 43L
  1537. ;            33H 33L
  1538. ;            23H 23L
  1539. ;        13H 13L 42H 42L
  1540. ;            32H 32L
  1541. ;        22H 22L
  1542. ;        12H 12L 41H 41L
  1543. ;        31H 31L
  1544. ;        21H 21L
  1545. ;    11H 11L
  1546. ;    ===d5== ===d6== =d7=
  1547.  
  1548.     move.w    d1,d7
  1549.     mulu.w    d5,d7            ;A2*B4
  1550.     clr.w    d7
  1551.     swap.w    d7
  1552.     move.w    d2,d6            ;24H
  1553.     mulu.w    d4,d6            ;A4*B2
  1554.     clr.w    d6
  1555.     swap.w    d6
  1556.     add.l    d6,d7            ;42H
  1557.     swap.w    d2            ;A43
  1558.     move.l    d5,d6
  1559.     swap.w    d6
  1560.     mulu.w    d2,d6            ;A3*B3
  1561.     clr.w    d6
  1562.     swap.w    d6
  1563.     add.l    d6,d7            ;33H
  1564.  
  1565.     move.l    d1,d6
  1566.     swap.w    d6
  1567.     mulu.w    d5,d6            ;A1*A4
  1568.     add.l    d6,d7            ;14L
  1569.     move.l    d7,d6
  1570.     clr.w    d6
  1571.     addx.w    d6,d6            ;14H(+桁上げ)
  1572.     swap.w    d6
  1573.  
  1574.     swap.w    d5
  1575.     move.w    d1,d3
  1576.     mulu.w    d5,d3            ;A2*B3
  1577.     add.w    d3,d7            ;23L
  1578.     clr.w    d3
  1579.     swap.w    d3
  1580.     addx.l    d3,d6            ;23H(+桁上げ)
  1581.  
  1582.     move.w    d4,d3
  1583.     mulu.w    d2,d3            ;A3*B2
  1584.     add.w    d3,d7            ;32L
  1585.     clr.w    d3
  1586.     swap.w    d3
  1587.     addx.l    d3,d6            ;32H(+桁上げ)
  1588.  
  1589.     move.l    d1,d3
  1590.     swap.w    d3
  1591.     mulu.w    d3,d5            ;A1*B3
  1592.     mulu.w    d4,d3            ;A1*B2
  1593.     move.w    d1,d0
  1594.     mulu.w    d4,d0            ;A2*B2
  1595.     add.l    d5,d0            ;13HL+22HL
  1596.     moveq.l    #0,d5
  1597.     addx.w    d5,d5            ;(桁上げ)
  1598.     add.l    d0,d6
  1599.     move.l    d3,d0
  1600.     swap.w    d3
  1601.     clr.w    d0
  1602.     swap.w    d0
  1603.     addx.l    d0,d5            ;12H(+桁上げ)
  1604.  
  1605.     swap.w    d4
  1606.     move.w    d2,d0
  1607.     swap.w    d2
  1608.     mulu.w    d4,d2            ;A4*B1
  1609.     add.w    d2,d7            ;41L
  1610.     swap.w    d2
  1611.     move.w    d2,d3
  1612.     addx.l    d3,d6            ;12L:41H(+桁上げ)
  1613.     move.l    d1,d3
  1614.     swap.w    d3
  1615.     mulu.w    d4,d3            ;A1*B1
  1616.     addx.l    d3,d5            ;11HL(+桁上げ)
  1617.  
  1618.     mulu.w    d4,d0            ;A3*B1
  1619.     add.l    d0,d6            ;31HL
  1620.     moveq.l    #0,d3
  1621.     addx.l    d3,d5            ;(桁上げ)
  1622.  
  1623.     mulu.w    d4,d1            ;A2*B1
  1624.     swap.w    d1
  1625.     move.w    d1,d3
  1626.     clr.w    d1
  1627.     add.l    d1,d6            ;21L
  1628.     addx.l    d3,d5            ;21H(+桁上げ)
  1629.  
  1630.     move.l    d5,d1
  1631.     move.l    d6,d2
  1632.     movem.w    (sp)+,d0/d3/d6
  1633.     ext.l    d0            ;(一時正規化数なら指数が負なので)
  1634.     ext.l    d3
  1635.     add.l    d3,d0            ;指数を加える
  1636.     sub.l    #$3FFF-1,d0        ;バイアスを引く
  1637.     tst.l    d1
  1638.     bmi    xmul5
  1639.     subq.l    #1,d0            ;正規化する
  1640.     add.w    d7,d7
  1641.     roxl.l    #1,d2
  1642.     roxl.l    #1,d1
  1643. xmul5:
  1644.     tst.w    d7            ;最下位ビットで丸めを行う
  1645.     bpl    xmul6
  1646.     moveq.l    #0,d3
  1647.     addq.l    #1,d2
  1648.     addx.l    d3,d1
  1649.     bcc    xmul6
  1650.     addq.l    #1,d0            ;丸めで桁上がりした
  1651.     move.l    #$80000000,d1        ;(結果は$80000000_00000000)
  1652. xmul6:
  1653.     cmp.w    #$7FFF,d0        ;(ワード範囲に収まる)
  1654.     bcs    xmul8            ;結果の指数が範囲内
  1655.     beq    xmul_i
  1656.     cmp.w    #-64,d0
  1657.     bgt    xmul7            ;一時正規化数の範囲内
  1658.     tst.l    d0
  1659.     bmi    xmul_z            ;値がアンダーフローした    →0
  1660.     bra    xmul_i            ;  オーバーフロー    →INF
  1661.  
  1662. xmul7:                    ;一時正規化数を非正規化数に戻す
  1663.     addq.w    #1,d0
  1664.     lsr.l    #1,d1
  1665.     roxr.l    #1,d2
  1666.     tst.w    d0
  1667.     bne    xmul7
  1668.     moveq.l    #0,d3            ;丸めを行う
  1669.     roxl.w    #1,d3            ;シフトではみだした最下位ビット
  1670.     add.l    d3,d2            ;最下位ビットを切り上げる(0捨1入)
  1671.     moveq.l    #0,d3
  1672.     addx.l    d3,d1
  1673. xmul8:
  1674.     tst.w    d6            ;結果の符号
  1675.     bpl    xmul9
  1676.     or.w    #$8000,d0
  1677. xmul9:
  1678.     movem.l    (sp)+,d3-d7
  1679.     rts
  1680.  
  1681. xmul_za:                ;A=0 or 非正規化数
  1682.     move.l    d1,d7
  1683.     or.l    d2,d7
  1684.     bne    xmul_za1        ;非正規化数の場合
  1685.     move.w    #$7FFF,d7
  1686.     and.w    d7,d3
  1687.     cmp.w    d7,d3
  1688.     beq    xmul_n            ;0*NAN or 0*INF = NAN
  1689. xmul_z:
  1690.     move.w    d6,d0            ;0*B = 0
  1691.     and.w    #$8000,d0
  1692.     moveq.l    #0,d1
  1693.     moveq.l    #0,d2
  1694.     movem.l    (sp)+,d3-d7
  1695.     rts
  1696.  
  1697. xmul_za1:                ;非正規化数を一時的に正規化する
  1698.     move.w    #$7FFF,d7
  1699. xmul_za2:
  1700.     tst.l    d1
  1701.     bmi    xmul1
  1702.     subq.w    #1,d0
  1703.     add.l    d2,d2
  1704.     addx.l    d1,d1
  1705.     bra    xmul_za2
  1706.  
  1707. xmul_nia:                ;A=NAN or ±INF
  1708.     add.l    d1,d1
  1709.     or.l    d2,d1
  1710.     bne    xmul_n            ;仮数部が0でないならNAN
  1711.     and.w    d7,d3            ;Bの指数
  1712.     beq    xmul_nia1        ;B=0 or 非正規化数
  1713.     cmp.w    d7,d3
  1714.     bne    xmul_i            ;INF*B = INF
  1715.     add.l    d4,d4
  1716.     or.l    d5,d4
  1717.     bne    xmul_n            ;仮数部が0でないならNAN
  1718. xmul_i:                    ;INFを返す
  1719.     move.w    d6,d0
  1720.     or.w    #$7FFF,d0
  1721.     moveq.l    #0,d1
  1722.     moveq.l    #0,d2
  1723.     movem.l    (sp)+,d3-d7
  1724.     rts
  1725.  
  1726. xmul_nia1:                ;B=0 or 非正規化数
  1727.     move.l    d4,d7
  1728.     or.l    d5,d7
  1729.     beq    xmul_n            ;INF*0 = NAN
  1730.     bra    xmul_i            ;INF*非正規化数 = INF
  1731.  
  1732. xmul_zb:                ;B=0 or 非正規化数
  1733.     move.l    d4,d7
  1734.     or.l    d5,d7
  1735.     beq    xmul_z            ;A*0 = 0
  1736. xmul_zb1:                ;非正規化数を一時的に正規化する
  1737.     tst.l    d4
  1738.     bmi    xmul2
  1739.     subq.w    #1,d3
  1740.     add.l    d5,d5
  1741.     addx.l    d4,d4
  1742.     bra    xmul_zb1
  1743.  
  1744. xmul_nib:                ;B=NAN or ±INF
  1745.     add.l    d4,d4
  1746.     or.l    d5,d4
  1747.     beq    xmul_i            ;A*INF = INF
  1748. xmul_n:                    ;NANを返す
  1749.     move.w    #$7FFF,d0
  1750.     moveq.l    #-1,d1
  1751.     moveq.l    #-1,d2
  1752.     movem.l    (sp)+,d3-d7
  1753.     rts
  1754.  
  1755. ;----------------------------------------------------------------
  1756. ;    2数を除算する(A=A/B)
  1757. ;    in :d0:d1:d2 = 拡張精度実数値A
  1758. ;        d3:d4:d5 = 拡張精度実数値B
  1759. ;    out:d0:d1:d2 = 結果
  1760. xdiv::
  1761.     movem.l    d3-d7,-(sp)
  1762.     move.w    d0,d6
  1763.     eor.w    d3,d6            ;結果の符号
  1764.     move.w    #$7FFF,d7
  1765.     and.w    d7,d0
  1766.     beq    xdiv_za            ;A=0 or 非正規化数
  1767.     cmp.w    d7,d0
  1768.     beq    xdiv_nia        ;A=NAN or ±INF
  1769. xdiv1:
  1770.     and.w    d7,d3
  1771.     beq    xdiv_zb            ;B=0 or 非正規化数
  1772.     cmp.w    d7,d3
  1773.     beq    xdiv_nib        ;B=NAN or ±INF
  1774. xdiv2:
  1775.     ext.l    d0            ;(一時正規化数なら指数が負なので)
  1776.     ext.l    d3
  1777.     sub.l    d3,d0            ;指数を引く
  1778.     add.l    #$3FFF,d0        ;バイアスを加える
  1779.  
  1780.     moveq.l    #0,d3
  1781.     cmp.l    d4,d1
  1782.     bne    xdiv3
  1783.     cmp.l    d5,d2
  1784. xdiv3:
  1785.     bcc    xdiv4
  1786.     moveq.l    #0,d7            ;A<B
  1787.     subq.l    #1,d0
  1788.     bra    xdiv5
  1789.  
  1790. xdiv4:                    ;A>B
  1791.     moveq.l    #1,d7
  1792.     sub.l    d5,d2
  1793.     subx.l    d4,d1
  1794. xdiv5:                    ;除算ループ
  1795.     add.l    d7,d7
  1796.     addx.l    d3,d3
  1797.     bcs    xdiv8            ;除算終了
  1798.     add.l    d2,d2            ;余り<<1
  1799.     addx.l    d1,d1
  1800.     bcs    xdiv7
  1801.     cmp.l    d4,d1
  1802.     bcs    xdiv5
  1803.     bne    xdiv7
  1804.     cmp.l    d5,d2
  1805.     bcs    xdiv5
  1806. xdiv7:
  1807.     sub.l    d5,d2
  1808.     subx.l    d4,d1
  1809.     addq.w    #1,d7
  1810.     bra    xdiv5
  1811.  
  1812. xdiv8:
  1813.     roxr.l    #1,d3
  1814.     roxr.l    #1,d7
  1815.     add.l    d2,d2
  1816.     addx.l    d1,d1
  1817.     bcs    xdiv9
  1818.     cmp.l    d4,d1
  1819.     bcs    xdiv10
  1820.     bne    xdiv9
  1821.     cmp.l    d5,d2
  1822.     bcs    xdiv10
  1823. xdiv9:
  1824.     moveq.l    #0,d1
  1825.     addq.l    #1,d7
  1826.     addx.l    d1,d3
  1827.     bcc    xdiv10
  1828.     addq.l    #1,d0            ;丸めで桁上がりした
  1829.     move.l    #$80000000,d3        ;(結果は$80000000_00000000)
  1830.  
  1831. xdiv10:
  1832.     move.l    d3,d1
  1833.     move.l    d7,d2
  1834.     cmp.w    #$7FFF,d0        ;(ワード範囲に収まる)
  1835.     bcs    xdiv24            ;結果の指数が範囲内
  1836.     cmp.w    #-64,d0
  1837.     bgt    xdiv23            ;一時正規化数の範囲内
  1838.     tst.l    d0
  1839.     bmi    xdiv_z            ;値がアンダーフローした    →0
  1840.     bra    xdiv_i            ;  オーバーフロー    →INF
  1841.  
  1842. xdiv23:                    ;一時正規化数を非正規化数に戻す
  1843.     addq.w    #1,d0
  1844.     lsr.l    #1,d1
  1845.     roxr.l    #1,d2
  1846.     tst.w    d0
  1847.     bne    xdiv23
  1848.     moveq.l    #0,d3            ;丸めを行う
  1849.     roxl.w    #1,d3            ;シフトではみだした最下位ビット
  1850.     add.l    d3,d2            ;最下位ビットを切り上げる(0捨1入)
  1851.     moveq.l    #0,d3
  1852.     addx.l    d3,d1
  1853. xdiv24:
  1854.     tst.w    d6            ;結果の符号
  1855.     bpl    xdiv25
  1856.     or.w    #$8000,d0
  1857. xdiv25:
  1858.     movem.l    (sp)+,d3-d7
  1859.     rts
  1860.  
  1861. xdiv_za:                ;A=0 or 非正規化数
  1862.     move.l    d1,d7
  1863.     or.l    d2,d7
  1864.     bne    xdiv_za5        ;非正規化数の場合
  1865.     move.w    #$7FFF,d7
  1866.     and.w    d7,d3            ;Bの指数
  1867.     beq    xdiv_za1        ;B=0 or 非正規化数
  1868.     cmp.w    d7,d3
  1869.     bne    xdiv_z            ;0/B = 0
  1870.     add.l    d4,d4
  1871.     or.l    d5,d4
  1872.     bne    xdiv_n            ;仮数部が0でないならNAN
  1873. xdiv_z:
  1874.     move.w    d6,d0            ;0/B = 0
  1875.     and.w    #$8000,d0
  1876.     moveq.l    #0,d1
  1877.     moveq.l    #0,d2
  1878.     movem.l    (sp)+,d3-d7
  1879.     rts
  1880.  
  1881. xdiv_za1:                ;B=0 or 非正規化数
  1882.     move.l    d4,d7
  1883.     or.l    d5,d7
  1884.     bne    xdiv_z            ;0/非正規化数 = 0
  1885.     bra    xdiv_n            ;0/0 = NAN
  1886.  
  1887. xdiv_za5:                ;非正規化数を一時的に正規化する
  1888.     move.w    #$7FFF,d7
  1889. xdiv_za6:
  1890.     tst.l    d1
  1891.     bmi    xdiv1
  1892.     subq.w    #1,d0
  1893.     add.l    d2,d2
  1894.     addx.l    d1,d1
  1895.     bra    xdiv_za6
  1896.  
  1897. xdiv_nia:                ;A=NAN or ±INF
  1898.     add.l    d1,d1
  1899.     or.l    d2,d1
  1900.     bne    xdiv_n            ;仮数部が0でないならNAN
  1901.     and.w    d7,d3            ;Bの指数
  1902.     cmp.w    d7,d3
  1903.     beq    xdiv_n            ;INF/NAN, INF/INF = NAN
  1904. xdiv_i:                    ;INFを返す
  1905.     move.w    d6,d0
  1906.     or.w    #$7FFF,d0
  1907.     moveq.l    #0,d1
  1908.     moveq.l    #0,d2
  1909.     movem.l    (sp)+,d3-d7
  1910.     rts
  1911.  
  1912. xdiv_zb:                ;B=0 or 非正規化数
  1913.     move.l    d4,d7
  1914.     or.l    d5,d7
  1915.     beq    xdiv_i            ;A/0 = INF
  1916. xdiv_zb1:                ;非正規化数を一時的に正規化する
  1917.     tst.l    d4
  1918.     bmi    xdiv2
  1919.     subq.w    #1,d3
  1920.     add.l    d5,d5
  1921.     addx.l    d4,d4
  1922.     bra    xdiv_zb1
  1923.  
  1924. xdiv_nib:                ;B=NAN or ±INF
  1925.     add.l    d4,d4
  1926.     or.l    d5,d4
  1927.     beq    xdiv_z            ;A/INF = 0
  1928. xdiv_n:                    ;NANを返す
  1929.     move.w    #$7FFF,d0
  1930.     moveq.l    #-1,d1
  1931.     moveq.l    #-1,d2
  1932.     movem.l    (sp)+,d3-d7
  1933.     rts
  1934.  
  1935. ;----------------------------------------------------------------
  1936. ;    正規化する
  1937. ;    in :d0:d1:d2 = 拡張精度実数値
  1938. ;    out:d0:d1:d2 = 結果
  1939. normalize:
  1940.     move.l    d3,-(sp)
  1941.     move.w    d0,d3
  1942.     and.w    #$7FFF,d3
  1943.     beq    normalize9        ;指数部が0ならなにもしない
  1944.     cmp.w    #$7FFF,d3
  1945.     beq    normalize_ni        ;NAN or ±INF
  1946.     tst.l    d1
  1947.     bmi    normalize9        ;すでに正規化されている
  1948.     bne    normalize1
  1949.     tst.l    d2
  1950.     beq    normalize_z        ;仮数部が0なら0
  1951. normalize1:
  1952.     subq.w    #1,d0
  1953.     add.l    d2,d2
  1954.     addx.l    d1,d1
  1955.     bmi    normalize9        ;正規化が終了した
  1956.     subq.w    #1,d3
  1957.     bne    normalize1        ;指数部が0になったら正規化を中断する
  1958. normalize9:
  1959.     move.l    (sp)+,d3
  1960.     rts
  1961.  
  1962. normalize_z:                ;0
  1963.     and.w    #$8000,d0
  1964.     bra    normalize9
  1965.  
  1966. normalize_ni:                ;NAN or ±INF
  1967.     add.l    d1,d1
  1968.     or.l    d2,d1
  1969.     beq    normalize9        ;INF
  1970. normalize_n:                ;NAN
  1971.     moveq.l    #-1,d1
  1972.     moveq.l    #-1,d2
  1973.     bra    normalize9
  1974.  
  1975. ;----------------------------------------------------------------
  1976. ;    64bit整数を拡張精度に変換する
  1977. ;    in :d1:d0 = 64bit整数
  1978. ;    out:d0:d1:d2 = 結果
  1979. qtox:
  1980.     move.l    d0,d2
  1981.     or.l    d1,d2
  1982.     beq    qtox9            ;0
  1983.     tst.l    d1
  1984.     beq    qtox3            ;d1=0なので下位32bitを拡張精度にする
  1985.     bpl    qtox2
  1986. ;負数
  1987.     neg.l    d0
  1988.     negx.l    d1
  1989.     bsr    qtox1
  1990.     bchg.l    #15,d0
  1991. qtox9:
  1992.     rts
  1993.  
  1994. ;d1=0なので下位32bitを拡張精度にする
  1995. qtox3:
  1996.     moveq.l    #0,d2
  1997.     move.l    d0,d1
  1998.     bra    ltox1
  1999.  
  2000. qtox1:
  2001.     tst.l    d1
  2002.     beq    qtox3            ;d1=0なので下位32bitを拡張精度にする
  2003. ;d1=0ではない
  2004. qtox2:
  2005.     move.l    d0,d2
  2006.     beq    qtox4            ;d0=0なので上位32bitだけシフトする
  2007. ;d1,d0共に0でないので全体をシフトする
  2008.     move.l    #$3FFF+63,d0        ;指数部は2^63
  2009.     tst.l    d1
  2010.     bra    qtox7
  2011.  
  2012. qtox6:
  2013.     add.l    d2,d2
  2014.     addx.l    d1,d1
  2015. qtox7:
  2016.     dbmi    d0,qtox6
  2017.     rts
  2018.  
  2019. ;d0=0なので上位32bitだけシフトする
  2020. qtox4:
  2021. ;d2=0
  2022.     move.l    d1,d0
  2023.     swap.w    d0
  2024.     tst.w    d0
  2025.     beq    qtox5
  2026.     move.l    #$3FFF+63,d0        ;指数部は2^63
  2027.     tst.l    d1
  2028.     bra    ltox3
  2029.  
  2030. qtox5:
  2031.     move.l    #$3FFF+47,d0        ;指数部は2^47
  2032.     tst.w    d1
  2033.     bra    ltox7
  2034.  
  2035. ;----------------------------------------------------------------
  2036. ;    ロングワード整数を拡張精度に変換する
  2037. ;    in :d0 = ロングワード整数値
  2038. ;    out:d0:d1:d2 = 結果
  2039. ltox::
  2040.     moveq.l    #0,d2
  2041.     move.l    d0,d1
  2042.     beq    ltox9            ;0の場合
  2043.     bpl    ltox1
  2044.     neg.l    d0            ;負数なら変換後に符号ビットをセットする
  2045.     move.l    d0,d1
  2046.     bsr    ltox1
  2047.     bchg.l    #15,d0
  2048. ltox9:
  2049.     rts
  2050.  
  2051. ltox1:
  2052.     swap.w    d0
  2053.     tst.w    d0
  2054.     beq    ltox5
  2055.     move.l    #$3FFF+31,d0        ;指数部は2^31
  2056.     tst.l    d1
  2057.     bra    ltox3
  2058.  
  2059. ltox2:
  2060.     add.l    d1,d1            ;左シフトして正規化する
  2061. ltox3:
  2062.     dbmi    d0,ltox2
  2063.     rts
  2064.  
  2065. ltox5:                    ;$00000001~$0000FFFFの場合
  2066.     move.l    #$3FFF+15,d0        ;指数部は2^15
  2067.     tst.w    d1
  2068.     bra    ltox7
  2069.  
  2070. ltox6:
  2071.     add.w    d1,d1            ;左シフトして正規化する
  2072. ltox7:
  2073.     dbmi    d0,ltox6
  2074.     swap.w    d1
  2075.     rts
  2076.  
  2077. ;----------------------------------------------------------------
  2078. ;    単精度実数を拡張精度に変換する
  2079. ;    in :d0 = 単精度実数値
  2080. ;    out:d0:d1:d2 = 結果
  2081. stox::
  2082.     move.l    d0,d1
  2083.     move.l    d0,d2
  2084.     add.l    d2,d2            ;符号ビット
  2085.     moveq.l    #0,d2
  2086.     roxr.w    #1,d2
  2087.     and.l    #$007FFFFF,d1        ;仮数部
  2088.     swap.w    d0
  2089.     lsr.w    #7,d0            ;d0.b=指数部
  2090.     tst.b    d0
  2091.     beq    stox_zn            ;0 or 非正規化数
  2092.     cmp.b    #$FF,d0
  2093.     beq    stox_ni            ;NAN or ±INF
  2094.     lsl.l    #8,d1            ;正規化数
  2095.     bset.l    #31,d1            ;仮数部整数ビット
  2096.     move.b    d0,d2
  2097.     add.w    #$3FFF-$7F,d2
  2098.     move.l    d2,d0            ;指数部
  2099.     moveq.l    #0,d2
  2100.     rts
  2101.  
  2102. stox_zn:                ;0 or 非正規化数
  2103.     move.l    d2,d0            ;指数部
  2104.     tst.l    d1
  2105.     beq    stox_z            ;0
  2106.     lsl.l    #8,d1            ;非正規化数
  2107.     add.w    #$3FFF-$7F+1,d0
  2108.     moveq.l    #0,d2
  2109.     bra    normalize        ;正規化する
  2110.  
  2111. stox_z:
  2112.     rts
  2113.  
  2114. stox_ni:                ;NAN or ±INF
  2115.     or.w    #$7FFF,d2
  2116.     move.l    d2,d0            ;指数部
  2117.     tst.l    d1
  2118.     beq    stox_i            ;INF
  2119.     moveq.l    #-1,d1            ;NANを返す
  2120.     moveq.l    #-1,d2
  2121.     rts
  2122.  
  2123. stox_i:
  2124.     moveq.l    #0,d1            ;INFを返す
  2125.     moveq.l    #0,d2
  2126.     rts
  2127.  
  2128. ;----------------------------------------------------------------
  2129. ;    倍精度実数を拡張精度に変換する
  2130. ;    in :d0:d1 = 倍精度実数値
  2131. ;    out:d0:d1:d2 = 結果
  2132. dtox::
  2133.     move.l    d3,-(sp)
  2134.     move.l    d0,d2
  2135.     clr.w    d0
  2136.     swap.w    d0
  2137.     add.l    d0,d0
  2138.     lsr.w    #5,d0            ;符号ビットと指数部を分離する
  2139.     and.l    #$000FFFFF,d2
  2140.     tst.w    d0
  2141.     beq    dtox_zn            ;0 or 非正規化数
  2142.     cmp.w    #$7FF,d0
  2143.     beq    dtox_ni            ;NAN or ±INF
  2144.     bset.l    #$14,d2            ;整数ビット
  2145.     move.l    d1,d3
  2146.     move.w    d2,d3
  2147.     lsr.l    #5,d2
  2148.     ror.l    #5,d1
  2149.     ror.l    #5,d3
  2150.     swap.w    d1
  2151.     and.w    #$F800,d1
  2152.     swap.w    d2
  2153.     swap.w    d3
  2154.     move.w    d3,d2            ;lsl #11,d2:d3 (整数ビットを最上位に上げる)
  2155.     exg.l    d1,d2
  2156.     add.w    #$3FFF-$3FF,d0
  2157.     add.w    d0,d0
  2158.     lsr.l    #1,d0            ;符号ビットを付け加える
  2159. dtox_z:
  2160.     move.l    (sp)+,d3
  2161.     rts
  2162.  
  2163. dtox_zn:                ;0 or 非正規化数
  2164.     lsr.l    #1,d0            ;符号ビットを付け加える
  2165.     move.l    d2,d3
  2166.     or.l    d1,d3
  2167.     beq    dtox_z            ;0
  2168.     add.w    #$3FFF-$3FF+12,d0    ;非正規化数
  2169.     exg.l    d1,d2
  2170.     move.l    (sp)+,d3
  2171.     bra    normalize        ;正規化する
  2172.  
  2173. dtox_ni:                ;NAN or ±INF
  2174.     move.w    #$FFFF,d0
  2175.     lsr.l    #1,d0            ;符号ビットを付け加える
  2176.     move.l    d2,d3
  2177.     or.l    d1,d3
  2178.     beq    dtox_i            ;INF
  2179.     moveq.l    #-1,d1            ;NANを返す
  2180.     moveq.l    #-1,d2
  2181.     move.l    (sp)+,d3
  2182.     rts
  2183.  
  2184. dtox_i:
  2185.     moveq.l    #0,d1            ;INFを返す
  2186.     moveq.l    #0,d2
  2187.     move.l    (sp)+,d3
  2188.     rts
  2189.  
  2190. ;----------------------------------------------------------------
  2191. ;    パックドデシマルを拡張精度実数に変換する
  2192. ;    in :d0:d1:d2 = パックドデシマル
  2193. ;    out:d0:d1:d2 = 結果
  2194. ptox::
  2195.     movem.l    d3-d7/a0-a1,-(sp)
  2196.     swap.w    d0
  2197.     move.w    d0,-(sp)
  2198.     and.w    #$7FFF,d0
  2199.     cmp.w    #$7FFF,d0
  2200.     beq    ptox_ni            ;NAN or ±INF
  2201.     clr.w    d0
  2202.     swap.w    d0
  2203.     moveq.l    #0,d3
  2204.     moveq.l    #0,d4
  2205.     moveq.l    #0,d5            ;d3:d4:d5 = +0.0
  2206.     move.l    d2,-(sp)
  2207.     move.l    d1,d7
  2208.     moveq.l    #8+1-1,d6
  2209.     bra    ptox2
  2210.  
  2211. ptox1:                    ;BCD16~8桁目を変換する
  2212.     move.w    #$4002,d3
  2213.     move.l    #$A0000000,d4
  2214.     moveq.l    #0,d5            ;d3:d4:d5 = +10.0
  2215.     bsr    xmul
  2216.     move.w    d0,d3
  2217.     move.l    d1,d4
  2218.     move.l    d2,d5
  2219.     rol.l    #4,d7
  2220.     moveq.l    #0,d0
  2221.     move.w    d7,d0
  2222. ptox2:
  2223.     and.w    #$000F,d0
  2224.     cmp.w    #9,d0
  2225.     bls    ptox3
  2226.     moveq.l    #0,d0            ;BCDの範囲外なら0
  2227. ptox3:
  2228.     bsr    ltox
  2229.     bsr    xadd
  2230.     dbra    d6,ptox1
  2231.  
  2232.     move.l    (sp)+,d7
  2233.     moveq.l    #8-1,d6
  2234. ptox4:                    ;BCD7~0桁目を変換する
  2235.     move.w    #$4002,d3
  2236.     move.l    #$A0000000,d4
  2237.     moveq.l    #0,d5            ;d3:d4:d5 = +10.0
  2238.     bsr    xmul
  2239.     move.w    d0,d3
  2240.     move.l    d1,d4
  2241.     move.l    d2,d5
  2242.     rol.l    #4,d7
  2243.     moveq.l    #0,d0
  2244.     move.w    d7,d0
  2245.     and.w    #$000F,d0
  2246.     cmp.w    #9,d0
  2247.     bls    ptox5
  2248.     moveq.l    #0,d0            ;BCDの範囲外なら0
  2249. ptox5:
  2250.     bsr    ltox
  2251.     bsr    xadd
  2252.     dbra    d6,ptox4
  2253.  
  2254.     move.w    (sp),d3            ;10進指数を2進変換する
  2255.     movem.l    d0-d2,-(sp)        ;仮数部
  2256.     rol.w    #4,d3
  2257.     moveq.l    #3-1,d6
  2258.     moveq.l    #0,d7
  2259. ptox_e1:
  2260.     add.w    d7,d7
  2261.     move.w    d7,d5
  2262.     add.w    d7,d7
  2263.     add.w    d7,d7
  2264.     add.w    d5,d7            ;d7.w *= 10
  2265.     rol.w    #4,d3
  2266.     move.w    d3,d5
  2267.     and.w    #$000F,d5
  2268.     cmp.w    #9,d5
  2269.     bls    ptox_e2
  2270.     moveq.l    #0,d5
  2271. ptox_e2:
  2272.     add.w    d5,d7
  2273.     dbra    d6,ptox_e1
  2274.     and.w    #$4000,d3
  2275.     beq    ptox_e3            ;指数部符号は正
  2276.     neg.w    d7            ;指数部符号を反転する
  2277. ptox_e3:                ;(d7.w = -999~999)
  2278.     move.w    #$3FFF,d0
  2279.     move.l    #$80000000,d1
  2280.     moveq.l    #0,d2            ;d0:d1:d2 = 1.0
  2281.     sub.w    #16,d7            ;仮数変換時の補正(d7.w = -1015~983)
  2282.     moveq.l    #10-1,d6
  2283.     tst.w    d7
  2284.     bmi    ptox_m
  2285.                     ;10進指数から10^nを得る
  2286. ptox_p:                    ;正の指数(1.0以上)の場合
  2287.     lea.l    (decexptblp+3*2,pc),a0    ;10^512から開始
  2288.     lea.l    (decmantblp+3*8,pc),a1
  2289.     rol.w    #6-1,d7            ;(必ず1024以下なので指数上位6bitは無視)
  2290. ptox_p1:
  2291.     move.w    (a0)+,d3
  2292.     movem.l    (a1)+,d4-d5
  2293.     add.w    d7,d7
  2294.     bpl    ptox_p2
  2295.     bsr    xmul            ;10の累乗を掛ける
  2296. ptox_p2:
  2297.     dbra    d6,ptox_p1
  2298.     bra    ptox_8
  2299.  
  2300. ptox_m:                    ;負の指数(1.0未満)の場合
  2301.     lea.l    (decexptblm+3*2,pc),a0    ;10^-512から開始
  2302.     lea.l    (decmantblm+3*8,pc),a1
  2303.     neg.w    d7
  2304.     rol.w    #6-1,d7            ;(必ず1024以下なので指数上位6bitは無視)
  2305. ptox_m1:
  2306.     move.w    (a0)+,d3
  2307.     movem.l    (a1)+,d4-d5
  2308.     add.w    d7,d7
  2309.     bpl    ptox_m2
  2310.     bsr    xmul            ;10の累乗を掛ける
  2311. ptox_m2:
  2312.     dbra    d6,ptox_m1
  2313.  
  2314. ptox_8:
  2315.     movem.l    (sp)+,d3-d5        ;仮数部
  2316.     bsr    xmul            ;仮数部×(10^指数部)
  2317.     tst.w    (sp)+
  2318.     bpl    ptox_9
  2319.     or.w    #$8000,d0        ;仮数部符号は負
  2320. ptox_9:
  2321.     movem.l    (sp)+,d3-d7/a0-a1
  2322.     rts
  2323.  
  2324. ptox_ni:                ;NAN or ±INF
  2325.     move.w    (sp)+,d0
  2326.     add.l    d1,d1
  2327.     or.l    d2,d1
  2328.     bne    ptox_n            ;仮数部が0でないならNAN
  2329. ptox_i:                    ;INF
  2330.     moveq.l    #0,d1
  2331.     moveq.l    #0,d2
  2332.     movem.l    (sp)+,d3-d7/a0-a1
  2333.     rts
  2334.  
  2335. ptox_n:                    ;NAN
  2336.     moveq.l    #-1,d1
  2337.     moveq.l    #-1,d2
  2338.     movem.l    (sp)+,d3-d7/a0-a1
  2339.     rts
  2340.  
  2341. ;----------------------------------------------------------------
  2342. ;    拡張精度実数をロングワード整数に変換する
  2343. ;    in :d0:d1:d2 = 拡張精度実数値
  2344. ;    out:d0 = 結果
  2345. ;        d1 = オーバーフローなどで変換できなければ-1
  2346. xtol::
  2347.     move.w    d0,d2            ;符号をセーブする
  2348.     swap.w    d2
  2349.     and.w    #$7FFF,d0
  2350.     beq    xtol_z            ;0 or 非正規化数→0
  2351.     move.w    #$3FFF+31,d2
  2352.     sub.w    d0,d2
  2353.     bcs    xtol_e            ;オーバーフロー
  2354.     cmp.w    #31,d2
  2355.     bhi    xtol_z            ;アンダーフロー→0
  2356.     lsr.l    d2,d1            ;仮数部をシフトする
  2357.     bmi    xtol5
  2358.     tst.l    d2            ;符号を付け加える
  2359.     bpl    xtol1
  2360.     neg.l    d1            ;負数の場合
  2361. xtol1:
  2362.     move.l    d1,d0
  2363.     moveq.l    #0,d1            ;変換できた
  2364.     rts
  2365.  
  2366. xtol5:                    ;2147483648~4294967297
  2367.     tst.l    d2
  2368.     bpl    xtol1            ;正数の場合
  2369.     cmp.l    #$80000000,d1        ;$80000000の場合だけ特別扱いする
  2370.     beq    xtol1
  2371. xtol_e:                    ;エラー
  2372.     moveq.l    #-1,d0
  2373.     moveq.l    #-1,d1
  2374.     rts
  2375.  
  2376. xtol_z:                    ;0 or アンダーフロー
  2377.     moveq.l    #0,d0
  2378.     moveq.l    #0,d1
  2379.     rts
  2380.  
  2381. ;----------------------------------------------------------------
  2382. ;    拡張精度実数を単精度に変換する
  2383. ;    in :d0:d1:d2 = 拡張精度実数値
  2384. ;    out:d0 = 結果
  2385. xtos::
  2386.     move.w    d0,-(sp)        ;符号をセーブする
  2387.     and.w    #$7FFF,d0
  2388.     beq    xtos_z            ;0 or 非正規化数
  2389.     cmp.w    #$3FFF+$FF-$7F,d0
  2390.     bcc    xtos_ni            ;NAN or ±INF or オーバーフロー
  2391.     sub.w    #$3FFF-$7F,d0
  2392.     bhi    xtos5            ;変換後は正規化数になる
  2393.     beq    xtos6            ;変換後は非正規化数になる
  2394.     neg.w    d0
  2395.     cmp.w    #23,d0
  2396.     bhi    xtos_z            ;非正規化の範囲外なので0になる
  2397.     lsr.l    d0,d1
  2398.     moveq.l    #0,d0            ;非正規化数の指数は0になる
  2399.     bra    xtos6
  2400.  
  2401. xtos5:
  2402.     add.l    d1,d1            ;仮数部整数ビットを削除する
  2403. xtos6:
  2404.     btst.l    #31-23,d1        ;23ビット目で丸めを行う
  2405.     beq    xtos_7            ;(IEEEのRounding to Nearestだと,0.5は最下位
  2406.     add.l    #1<<(31-23),d1        ; ビットが偶数になるように丸めるのが正しいが,
  2407.     bcc    xtos_7            ; ここでは0.5は必ず無限大方向に丸められる)
  2408.     addq.w    #1,d0
  2409.     cmp.w    #$FF,d0
  2410.     beq    xtos_i            ;丸めの結果オーバーフローした
  2411. xtos_7:
  2412.     move.b    d0,d1            ;指数部を付け加える
  2413.     ror.l    #8,d1
  2414.     lsl.w    (sp)+            ;保存してあった符号を調べる
  2415.     roxr.l    #1,d1            ;符号ビットを付け加える
  2416.     move.l    d1,d0
  2417.     rts
  2418.  
  2419. xtos_z:                    ;0 or 非正規化数
  2420.     moveq.l    #0,d0            ;拡張精度での非正規化数は0になる
  2421.     lsl.w    (sp)+            ;保存してあった符号を調べる
  2422.     roxr.l    #1,d0            ;符号ビットを付け加える
  2423.     rts
  2424.  
  2425. xtos_ni:                ;NAN or ±INF or オーバーフロー
  2426.     cmp.w    #$7FFF,d0
  2427.     bne    xtos_i            ;オーバーフロー → INF
  2428.     add.l    d1,d1
  2429.     or.l    d2,d1
  2430.     beq    xtos_i
  2431. xtos_n:
  2432.     moveq.l    #-1,d0            ;NAN
  2433.     bra    xtos_i9
  2434.  
  2435. xtos_i:
  2436.     move.l    #$FF000000,d0        ;INF
  2437. xtos_i9:
  2438.     lsl.w    (sp)+            ;保存してあった符号を調べる
  2439.     roxr.l    #1,d0            ;符号ビットを付け加える
  2440.     rts
  2441.  
  2442. ;----------------------------------------------------------------
  2443. ;    拡張精度実数を倍精度に変換する
  2444. ;    in :d0:d1:d2 = 拡張精度実数値
  2445. ;    out:d0:d1 = 結果
  2446. xtod::
  2447.     move.w    d0,-(sp)        ;符号をセーブする
  2448.     and.w    #$7FFF,d0
  2449.     beq    xtod_z            ;0 or 非正規化数
  2450.     cmp.w    #$3FFF+$7FF-$3FF,d0
  2451.     bcc    xtod_ni            ;NAN or ±INF or オーバーフロー
  2452.     sub.w    #$3FFF-$3FF,d0
  2453.     bhi    xtod5            ;変換後は正規化数になる
  2454.     beq    xtod6            ;変換後は非正規化数になる
  2455.  
  2456.     neg.w    d0
  2457.     cmp.w    #52,d0
  2458.     bhi    xtod_z            ;非正規化の範囲外なので0になる
  2459.     subq.w    #1,d0
  2460. xtod1:
  2461.     lsr.l    #1,d1
  2462.     roxr.l    #1,d2
  2463.     dbra    d0,xtod1
  2464.     moveq.l    #0,d0            ;非正規化数の指数は0になる
  2465.     bra    xtod6
  2466.  
  2467. xtod5:
  2468.     add.l    d2,d2            ;仮数部整数ビットを削除する
  2469.     addx.l    d1,d1
  2470. xtod6:
  2471.     btst.l    #31-(52-32),d2        ;52ビット目で丸めを行う
  2472.     beq    xtod_7            ;(IEEEのRounding to Nearestだと,0.5は最下位
  2473.     add.l    #1<<(31-(52-32)),d2    ; ビットが偶数になるように丸めるのが正しいが,
  2474.     bcc    xtod_7            ; ここでは0.5は必ず無限大方向に丸められる)
  2475.     addq.l    #1,d1
  2476.     bcc    xtod_7
  2477.     addq.w    #1,d0
  2478.     cmp.w    #$7FF,d0
  2479.     beq    xtod_i            ;丸めの結果オーバーフローした
  2480. xtod_7:
  2481.     and.l    #$FFFFF000,d2        ;仮数部不要ビットをクリアする
  2482.     or.w    d0,d2            ;指数部を付け加える
  2483.     swap.w    d2
  2484.     swap.w    d1
  2485.     move.l    d2,d0
  2486.     move.w    d1,d0
  2487.     move.w    d2,d1
  2488.  
  2489.     move.l    d1,d2
  2490.     move.w    d0,d2
  2491.     rol.l    #5,d0
  2492.     rol.l    #5,d1
  2493.     rol.l    #5,d2
  2494.     and.w    #$001F,d0
  2495.     and.w    #$FFE0,d1
  2496.     or.w    d0,d1
  2497.     move.w    d2,d0
  2498.  
  2499.     lsl.w    (sp)+            ;保存してあった符号を調べる
  2500.     roxr.l    #1,d0            ;符号ビットを付け加える
  2501.     roxr.l    #1,d1
  2502.     rts
  2503.  
  2504. xtod_z:                    ;0 or 非正規化数
  2505.     moveq.l    #0,d0            ;拡張精度での非正規化数は0になる
  2506.     moveq.l    #0,d1
  2507.     lsl.w    (sp)+            ;保存してあった符号を調べる
  2508.     roxr.l    #1,d0            ;符号ビットを付け加える
  2509.     rts
  2510.  
  2511. xtod_ni:                ;NAN or ±INF or オーバーフロー
  2512.     cmp.w    #$7FFF,d0
  2513.     bne    xtod_i            ;オーバーフロー → INF
  2514.     add.l    d1,d1
  2515.     or.l    d2,d1
  2516.     beq    xtod_i
  2517. xtod_n:
  2518.     moveq.l    #-1,d0            ;NAN
  2519.     moveq.l    #-1,d1
  2520.     bra    xtod_i9
  2521.  
  2522. xtod_i:
  2523.     move.l    #$FF000000,d0        ;INF
  2524.     moveq.l    #0,d1
  2525. xtod_i9:
  2526.     lsl.w    (sp)+            ;保存してあった符号を調べる
  2527.     roxr.l    #1,d0            ;符号ビットを付け加える
  2528.     rts
  2529.  
  2530. ;----------------------------------------------------------------
  2531. ;    拡張精度実数をパックドデシマルに変換する
  2532. ;    in :d0:d1:d2 = 拡張精度実数値
  2533. ;    out:d0:d1:d2 = 結果
  2534. xtop::
  2535.     link    a6,#-18
  2536.     movem.l    d3-d7/a0-a1,-(sp)
  2537.     move.w    d0,d6
  2538.     move.w    #$7FFF,d7
  2539.     and.w    d7,d6
  2540.     beq    xtop_zn            ;0 or 非正規化数
  2541.     cmp.w    d7,d6
  2542.     beq    xtop_ni            ;NAN or ±INF
  2543. xtop1:
  2544.     move.w    d0,-(sp)        ;仮数部符号
  2545.     move.w    d6,d0
  2546.     move.w    #4096*2,d6
  2547.     moveq.l    #0,d7
  2548.     cmp.w    #$3FFF,d0
  2549.     bcs    xtop_m            ;1.0未満の場合
  2550.  
  2551.     lea.l    (decmantblp,pc),a0    ;1.0以上の場合
  2552.     lea.l    (decexptblp,pc),a1    ;1.0以上10.0未満の値に補正する
  2553. xtop_p1:
  2554.     move.w    (a1)+,d3        ;10進指数テーブルから数値を得る
  2555.     beq    xtop_man
  2556.     movem.l    (a0)+,d4-d5
  2557.     lsr.w    #1,d6
  2558.     cmp.w    d3,d0
  2559.     bcs    xtop_p1
  2560.     bhi    xtop_p3
  2561.     cmp.l    d4,d1
  2562.     bne    xtop_p2
  2563.     cmp.l    d5,d2
  2564. xtop_p2:
  2565.     bcs    xtop_p1
  2566. xtop_p3:                ;テーブルの値より大きいならその逆数を掛ける
  2567.     add.w    d6,d7
  2568.     move.w    (decexptblm-(decexptblp+2),a1),d3
  2569.     movem.l    (decmantblm-(decmantblp+8),a0),d4-d5
  2570.     bsr    xmul
  2571.     bra    xtop_p1
  2572.  
  2573. xtop_m:
  2574.     lea.l    (decmantblm,pc),a0    ;1.0未満の場合
  2575.     lea.l    (decexptblm,pc),a1    ;0.1以上1.0未満の値に補正する
  2576. xtop_m1:
  2577.     move.w    (a1)+,d3        ;10進指数テーブルから数値を得る
  2578.     beq    xtop_man0
  2579.     movem.l    (a0)+,d4-d5
  2580.     lsr.w    #1,d6
  2581.     cmp.w    d3,d0
  2582.     bhi    xtop_m1
  2583.     bcs    xtop_m3
  2584.     cmp.l    d4,d1
  2585.     bne    xtop_m2
  2586.     cmp.l    d5,d2
  2587. xtop_m2:
  2588.     bcc    xtop_m1
  2589. xtop_m3:                ;テーブルの値より小さいならその逆数を掛ける
  2590.     sub.w    d6,d7
  2591.     move.w    (decexptblp-(decexptblm+2),a1),d3
  2592.     movem.l    (decmantblp-(decmantblm+8),a0),d4-d5
  2593.     bsr    xmul
  2594.     bra    xtop_m1
  2595.  
  2596. xtop_man0:                ;0.1以上1.0未満
  2597.     subq.w    #1,d7
  2598.     move.w    #$4002,d3
  2599.     move.l    #$A0000000,d4
  2600.     moveq.l    #0,d5
  2601.     bsr    xmul            ;10倍する
  2602.  
  2603. xtop_man:                ;1.0以上10.0未満の仮数部を10進数に変換する
  2604.     sub.w    #$3FFE,d0
  2605.     move.l    d1,d4
  2606.     clr.w    d4
  2607.     move.l    d2,d3
  2608.     move.w    d1,d3
  2609.     lsl.l    d0,d1
  2610.     lsl.l    d0,d2
  2611.     rol.l    d0,d3
  2612.     rol.l    d0,d4
  2613.     move.w    d3,d1            ;lsl d0,d4:d1:d2 小数点の位置を合わせる
  2614.     lea.l    (-17,a6),a0
  2615.     movea.l    a0,a1
  2616.     move.b    d4,(a0)+        ;10進仮数整数部
  2617.  
  2618.     moveq.l    #17-1,d0
  2619.     bra    xtop_man2
  2620.  
  2621. xtop_man1:
  2622.     move.b    d3,(a0)+
  2623. xtop_man2:
  2624.     moveq.l    #0,d3
  2625.     add.l    d2,d2
  2626.     addx.l    d1,d1
  2627.     addx.w    d3,d3            ;lsl d3:d1:d2
  2628.     move.l    d1,d4
  2629.     move.l    d2,d5
  2630.     move.w    d3,d6
  2631.     add.l    d5,d5
  2632.     addx.l    d4,d4
  2633.     addx.w    d6,d6            ;lsl d6:d4:d5
  2634.     add.l    d5,d5
  2635.     addx.l    d4,d4
  2636.     addx.w    d6,d6            ;lsl d6:d4:d5
  2637.     add.l    d5,d2
  2638.     addx.l    d4,d1
  2639.     addx.w    d6,d3            ;add d6:d4:d5,d3:d1:d2 (mulu #10,d3:d1:d2)
  2640.     dbra    d0,xtop_man1
  2641.  
  2642.     cmp.w    #-4933,d7
  2643.     bge    xtop_mrof
  2644.     move.w    d7,d0            ;-4933以下の指数なら非正規化する
  2645.     move.w    #-4933,d7
  2646.     add.w    #4933,d0
  2647.     moveq.l    #17-1,d2
  2648.     moveq.l    #0,d3
  2649.     cmp.w    #-17,d0
  2650.     blt    xtop_man5        ;-4933-17以下の指数なら0
  2651.     lea.l    (1,a0,d0.w),a1
  2652.     move.b    -(a1),d3        ;BCD最下位
  2653.     moveq.l    #17,d1
  2654.     add.w    d0,d1
  2655.     bra    xtop_man4
  2656.  
  2657. xtop_man3:
  2658.     move.b    -(a1),-(a0)        ;仮数部をシフトする
  2659. xtop_man4:
  2660.     dbra    d1,xtop_man3
  2661.     move.w    d0,d2
  2662.     neg.w    d2
  2663.     subq.w    #1,d2
  2664. xtop_man5:
  2665.     clr.b    -(a0)            ;仮数部上位に0を入れる
  2666.     dbra    d2,xtop_man5
  2667.     movea.l    a6,a0
  2668.     lea.l    (-17,a6),a1
  2669.  
  2670. xtop_mrof:                ;BCD最下位を四捨五入する
  2671.     cmp.w    #5,d3
  2672.     bcs    xtop_mrof3
  2673.     moveq.l    #17-1,d0
  2674. xtop_mrof1:
  2675.     move.b    -(a0),d1
  2676.     addq.b    #1,d1
  2677.     cmp.b    #9,d1
  2678.     bls    xtop_mrof2
  2679.     clr.b    (a0)
  2680.     dbra    d0,xtop_mrof1
  2681.     addq.w    #1,d7            ;四捨五入によって桁上がりした
  2682.     subq.l    #1,a0
  2683.     movea.l    a0,a1
  2684.     moveq.l    #1,d1
  2685. xtop_mrof2:
  2686.     move.b    d1,(a0)
  2687. xtop_mrof3:                ;BCDをパックする
  2688.     moveq.l    #0,d0
  2689.     move.b    (a1)+,d0        ;10進仮数整数部
  2690.     moveq.l    #16-1,d3
  2691. xtop_mrof4:
  2692.     move.l    d2,d4
  2693.     move.w    d1,d4
  2694.     lsl.l    #4,d2
  2695.     lsl.l    #4,d1
  2696.     rol.l    #4,d4
  2697.     move.w    d4,d1
  2698.     move.b    (a1)+,d4
  2699.     or.b    d4,d2
  2700.     dbra    d3,xtop_mrof4
  2701.  
  2702. xtop_exp:                ;指数部を作成する
  2703.     moveq.l    #0,d3
  2704.     move.w    d7,d3            ;指数
  2705.     bpl    xtop_exp1
  2706.     neg.w    d3            ;指数は負
  2707. xtop_exp1:
  2708.     lsl.w    #4,d0
  2709.     divu.w    #1000,d3        ;1000の位を得る
  2710.     or.w    d3,d0
  2711.     ror.w    #4,d0
  2712.     swap.w    d0
  2713.     clr.w    d3
  2714.     swap.w    d3
  2715.     divu.w    #100,d3            ;100の位を得る
  2716.     or.w    d3,d0
  2717.     rol.w    #4,d0
  2718.     clr.w    d3
  2719.     swap.w    d3
  2720.     divu.w    #10,d3            ;10の位を得る
  2721.     or.w    d3,d0
  2722.     rol.w    #4,d0
  2723.     swap.w    d3
  2724.     or.w    d3,d0            ;1の位
  2725.     tst.w    d7
  2726.     bpl    xtop_exp2
  2727.     or.w    #$4000,d0        ;指数部符号は負
  2728. xtop_exp2:
  2729.     tst.w    (sp)+
  2730.     bpl    xtop_exp3
  2731.     or.w    #$8000,d0        ;仮数部符号は負
  2732. xtop_exp3:
  2733.     swap.w    d0
  2734.     movem.l    (sp)+,d3-d7/a0-a1
  2735.     unlk    a6
  2736.     rts
  2737.  
  2738. xtop_zn:                ;0 or 非正規化数
  2739.     move.l    d1,d7
  2740.     or.l    d2,d7
  2741.     bne    xtop1
  2742. xtop_z:                    ;0の場合
  2743.     swap.w    d0
  2744.     clr.w    d0
  2745.     movem.l    (sp)+,d3-d7/a0-a1
  2746.     unlk    a6
  2747.     rts
  2748.  
  2749. xtop_ni:                ;NAN or ±INF
  2750.     add.l    d1,d1
  2751.     or.l    d2,d1
  2752.     bne    xtop_n            ;仮数部が0でないならNAN
  2753. xtop_i:                    ;INF
  2754.     swap.w    d0
  2755.     clr.w    d0
  2756.     moveq.l    #0,d1
  2757.     moveq.l    #0,d2
  2758.     movem.l    (sp)+,d3-d7/a0-a1
  2759.     unlk    a6
  2760.     rts
  2761.  
  2762. xtop_n:                    ;NAN
  2763.     swap.w    d0
  2764.     clr.w    d0
  2765.     moveq.l    #-1,d1
  2766.     moveq.l    #-1,d2
  2767.     movem.l    (sp)+,d3-d7/a0-a1
  2768.     unlk    a6
  2769.     rts
  2770.  
  2771. ;----------------------------------------------------------------
  2772. ;    10進指数変換用テーブル
  2773. decmantblp:
  2774.     .dc.l    $C4605202,$8A20979B    ;10^4096
  2775.     .dc.l    $9E8B3B5D,$C53D5DE5    ;10^2048
  2776.     .dc.l    $C9767586,$81750C17    ;10^1024
  2777.     .dc.l    $E319A0AE,$A60E91C7    ;10^512
  2778.     .dc.l    $AA7EEBFB,$9DF9DE8E    ;10^256
  2779.     .dc.l    $93BA47C9,$80E98CE0    ;10^128
  2780.     .dc.l    $C2781F49,$FFCFA6D5    ;10^64
  2781.     .dc.l    $9DC5ADA8,$2B70B59E    ;10^32
  2782.     .dc.l    $8E1BC9BF,$04000000    ;10^16
  2783.     .dc.l    $BEBC2000,$00000000    ;10^8
  2784.     .dc.l    $9C400000,$00000000    ;10^4
  2785.     .dc.l    $C8000000,$00000000    ;10^2
  2786.     .dc.l    $A0000000,$00000000    ;10^1
  2787.  
  2788. decexptblp:
  2789.     .dc.w    $7525            ;10^4096
  2790.     .dc.w    $5A92            ;10^2048
  2791.     .dc.w    $4D48            ;10^1024
  2792.     .dc.w    $46A3            ;10^512
  2793.     .dc.w    $4351            ;10^256
  2794.     .dc.w    $41A8            ;10^128
  2795.     .dc.w    $40D3            ;10^64
  2796.     .dc.w    $4069            ;10^32
  2797.     .dc.w    $4034            ;10^16
  2798.     .dc.w    $4019            ;10^8
  2799.     .dc.w    $400C            ;10^4
  2800.     .dc.w    $4005            ;10^2
  2801.     .dc.w    $4002            ;10^1
  2802.     .dc.w    0
  2803.  
  2804. decmantblm:
  2805.     .dc.l    $A6DD04C8,$D2CE9FDE    ;10^-4096
  2806.     .dc.l    $CEAE534F,$34362DE4    ;10^-2048
  2807.     .dc.l    $A2A682A5,$DA57C0BE    ;10^-1024
  2808.     .dc.l    $9049EE32,$DB23D21C    ;10^-512
  2809.     .dc.l    $C0314325,$637A193A    ;10^-256
  2810.     .dc.l    $DDD0467C,$64BCE4A0    ;10^-128
  2811.     .dc.l    $A87FEA27,$A539E9A5    ;10^-64
  2812.     .dc.l    $CFB11EAD,$453994BA    ;10^-32
  2813.     .dc.l    $E69594BE,$C44DE15B    ;10^-16
  2814.     .dc.l    $ABCC7711,$8461CEFD    ;10^-8
  2815.     .dc.l    $D1B71758,$E219652C    ;10^-4
  2816.     .dc.l    $A3D70A3D,$70A3D70A    ;10^-2
  2817.     .dc.l    $CCCCCCCC,$CCCCCCCD    ;10^-1
  2818.  
  2819. decexptblm:
  2820.     .dc.w    $0AD8            ;10^-4096
  2821.     .dc.w    $256B            ;10^-2048
  2822.     .dc.w    $32B5            ;10^-1024
  2823.     .dc.w    $395A            ;10^-512
  2824.     .dc.w    $3CAC            ;10^-256
  2825.     .dc.w    $3E55            ;10^-128
  2826.     .dc.w    $3F2A            ;10^-64
  2827.     .dc.w    $3F94            ;10^-32
  2828.     .dc.w    $3FC9            ;10^-16
  2829.     .dc.w    $3FE4            ;10^-8
  2830.     .dc.w    $3FF1            ;10^-4
  2831.     .dc.w    $3FF8            ;10^-2
  2832.     .dc.w    $3FFB            ;10^-1
  2833.     .dc.w    0
  2834.  
  2835.  
  2836. ;----------------------------------------------------------------
  2837.     .end
  2838.  
  2839. ;----------------------------------------------------------------
  2840. ;    $Log: fexpr.s,v $
  2841. ;    Revision 1.8  1999 10/ 6(Wed) 14:54:26 M.Kamada
  2842. ;    +86 浮動小数点数を含む式で+符号が使えなかった
  2843. ;    +86 浮動小数点数を含む式で加算と減算が逆になっていた
  2844. ;
  2845. ;    Revision 1.7  1999  6/ 9(Wed) 22:51:03 M.Kamada
  2846. ;    +85 演算子.notb./.notw.を追加
  2847. ;    +85 浮動小数点数を含む式で単項整数演算子が使えなかった
  2848. ;
  2849. ;    Revision 1.6  1999  3/15(Mon) 02:21:03 M.Kamada
  2850. ;    +83 浮動小数点数を含む式で比較と整数の演算子が使えるようにする
  2851. ;
  2852. ;    Revision 1.5  1999  2/28(Sun) 20:08:46 M.Kamada
  2853. ;    +82 エラーメッセージを日本語化
  2854. ;
  2855. ;    Revision 1.4  1999  2/27(Sat) 23:41:11 M.Kamada
  2856. ;    +81 ソースリストのフォーマットを変更(実行ファイルは+80とまったく同じ)
  2857. ;
  2858. ;    Revision 1.3  1997 10/28(Tue) 16:44:21 M.Kamada
  2859. ;    +52 PMOVE.D #imm,CRPが正しくアセンブルできない不具合
  2860. ;    +52 .DC.X 0.0+$FFFF9999がC00E00009999FFFF00000000になる不具合
  2861. ;    +52 浮動小数点数のサイズ指定を可能にする
  2862. ;    +52 .E+10が浮動小数点実数と判断されない不具合
  2863. ;
  2864. ;    Revision 1.2  1997  6/24(Tue) 22:01:51 M.Kamada
  2865. ;    +34 プレデファインシンボルに対応
  2866. ;
  2867. ;    Revision 1.1  1994/02/16  16:25:10  nakamura
  2868. ;    Initial revision
  2869. ;
  2870. ;
  2871.